function mxGraph(a, b, c, d) {
    this.mouseListeners = null;
    this.renderHint = c;
    this.dialect = mxClient.IS_SVG ? mxConstants.DIALECT_SVG: c == mxConstants.RENDERING_HINT_EXACT && mxClient.IS_VML ? mxConstants.DIALECT_VML: c == mxConstants.RENDERING_HINT_FASTEST ? mxConstants.DIALECT_STRICTHTML: c == mxConstants.RENDERING_HINT_FASTER ? mxConstants.DIALECT_PREFERHTML: mxConstants.DIALECT_MIXEDHTML;
    this.model = b != null ? b: new mxGraphModel;
    this.multiplicities = [];
    this.imageBundles = [];
    this.cellRenderer = this.createCellRenderer();
    this.setSelectionModel(this.createSelectionModel());
    this.setStylesheet(d != null ? d: this.createStylesheet());
    this.view = this.createGraphView();
    this.graphModelChangeListener = mxUtils.bind(this,
    function(a, b) {
        this.graphModelChanged(b.getProperty("edit").changes)
    });
    this.model.addListener(mxEvent.CHANGE, this.graphModelChangeListener);
    this.createHandlers();
    a != null && this.init(a);
    this.view.revalidate()
}
mxLoadResources && mxResources.add(mxClient.basePath + "/resources/graph");
mxGraph.prototype = new mxEventSource;
mxGraph.prototype.constructor = mxGraph;
mxGraph.prototype.EMPTY_ARRAY = [];
mxGraph.prototype.mouseListeners = null;
mxGraph.prototype.isMouseDown = !1;
mxGraph.prototype.model = null;
mxGraph.prototype.view = null;
mxGraph.prototype.stylesheet = null;
mxGraph.prototype.selectionModel = null;
mxGraph.prototype.cellEditor = null;
mxGraph.prototype.cellRenderer = null;
mxGraph.prototype.multiplicities = null;
mxGraph.prototype.renderHint = null;
mxGraph.prototype.dialect = null;
mxGraph.prototype.gridSize = 10;
mxGraph.prototype.gridEnabled = !0;
mxGraph.prototype.portsEnabled = !0;
mxGraph.prototype.doubleTapEnabled = !0;
mxGraph.prototype.doubleTapTimeout = 700;
mxGraph.prototype.doubleTapTolerance = 25;
mxGraph.prototype.lastTouchY = 0;
mxGraph.prototype.lastTouchY = 0;
mxGraph.prototype.lastTouchTime = 0;
mxGraph.prototype.gestureEnabled = !0;
mxGraph.prototype.tolerance = 4;
mxGraph.prototype.defaultOverlap = 0.5;
mxGraph.prototype.defaultParent = null;
mxGraph.prototype.alternateEdgeStyle = null;
mxGraph.prototype.backgroundImage = null;
mxGraph.prototype.pageVisible = !1;
mxGraph.prototype.pageBreaksVisible = !1;
mxGraph.prototype.pageBreakColor = "gray";
mxGraph.prototype.pageBreakDashed = !0;
mxGraph.prototype.minPageBreakDist = 20;
mxGraph.prototype.preferPageSize = !1;
mxGraph.prototype.pageFormat = mxConstants.PAGE_FORMAT_A4_PORTRAIT;
mxGraph.prototype.pageScale = 1.5;
mxGraph.prototype.enabled = !0;
mxGraph.prototype.escapeEnabled = !0;
mxGraph.prototype.invokesStopCellEditing = !0;
mxGraph.prototype.enterStopsCellEditing = !1;
mxGraph.prototype.useScrollbarsForPanning = !0;
mxGraph.prototype.exportEnabled = !0;
mxGraph.prototype.importEnabled = !0;
mxGraph.prototype.cellsLocked = !1;
mxGraph.prototype.cellsCloneable = !0;
mxGraph.prototype.foldingEnabled = !0;
mxGraph.prototype.cellsEditable = !0;
mxGraph.prototype.cellsDeletable = !0;
mxGraph.prototype.cellsMovable = !0;
mxGraph.prototype.edgeLabelsMovable = !0;
mxGraph.prototype.vertexLabelsMovable = !1;
mxGraph.prototype.dropEnabled = !1;
mxGraph.prototype.splitEnabled = !0;
mxGraph.prototype.cellsResizable = !0;
mxGraph.prototype.cellsBendable = !0;
mxGraph.prototype.cellsSelectable = !0;
mxGraph.prototype.cellsDisconnectable = !0;
mxGraph.prototype.autoSizeCells = !1;
mxGraph.prototype.autoScroll = !0;
mxGraph.prototype.timerAutoScroll = !1;
mxGraph.prototype.allowAutoPanning = !1;
mxGraph.prototype.ignoreScrollbars = !1;
mxGraph.prototype.autoExtend = !0;
mxGraph.prototype.maximumGraphBounds = null;
mxGraph.prototype.minimumGraphSize = null;
mxGraph.prototype.minimumContainerSize = null;
mxGraph.prototype.maximumContainerSize = null;
mxGraph.prototype.resizeContainer = !1;
mxGraph.prototype.border = 0;
mxGraph.prototype.ordered = !0;
mxGraph.prototype.keepEdgesInForeground = !1;
mxGraph.prototype.keepEdgesInBackground = !0;
mxGraph.prototype.allowNegativeCoordinates = !0;
mxGraph.prototype.constrainChildren = !0;
mxGraph.prototype.extendParents = !0;
mxGraph.prototype.extendParentsOnAdd = !0;
mxGraph.prototype.collapseToPreferredSize = !0;
mxGraph.prototype.zoomFactor = 1.2;
mxGraph.prototype.keepSelectionVisibleOnZoom = !1;
mxGraph.prototype.centerZoom = !0;
mxGraph.prototype.resetViewOnRootChange = !0;
mxGraph.prototype.resetEdgesOnResize = !1;
mxGraph.prototype.resetEdgesOnMove = !1;
mxGraph.prototype.resetEdgesOnConnect = !0;
mxGraph.prototype.allowLoops = !1;
mxGraph.prototype.defaultLoopStyle = mxEdgeStyle.Loop;
mxGraph.prototype.multigraph = !0;
mxGraph.prototype.connectableEdges = !1;
mxGraph.prototype.allowDanglingEdges = !0;
mxGraph.prototype.cloneInvalidEdges = !1;
mxGraph.prototype.disconnectOnMove = !0;
mxGraph.prototype.labelsVisible = !0;
mxGraph.prototype.htmlLabels = !1;
mxGraph.prototype.swimlaneSelectionEnabled = !0;
mxGraph.prototype.swimlaneNesting = !0;
mxGraph.prototype.swimlaneIndicatorColorAttribute = mxConstants.STYLE_FILLCOLOR;
mxGraph.prototype.imageBundles = null;
mxGraph.prototype.minFitScale = 0.1;
mxGraph.prototype.maxFitScale = 8;
mxGraph.prototype.panDx = 0;
mxGraph.prototype.panDy = 0;
mxGraph.prototype.collapsedImage = new mxImage(mxClient.imageBasePath + "/collapsed.gif", 9, 9);
mxGraph.prototype.expandedImage = new mxImage(mxClient.imageBasePath + "/expanded.gif", 9, 9);
mxGraph.prototype.warningImage = new mxImage(mxClient.imageBasePath + "/warning" + (mxClient.IS_MAC ? ".png": ".gif"), 16, 16);
mxGraph.prototype.alreadyConnectedResource = "none" != mxClient.language ? "alreadyConnected": "";
mxGraph.prototype.containsValidationErrorsResource = "none" != mxClient.language ? "containsValidationErrors": "";
mxGraph.prototype.collapseExpandResource = "none" != mxClient.language ? "collapse-expand": "";
mxGraph.prototype.init = function(a) {
    this.container = a;
    this.cellEditor = this.createCellEditor();
    this.view.init();
    this.sizeDidChange();
    if (mxClient.IS_IE) {
        mxEvent.addListener(window, "unload", mxUtils.bind(this,
        function() {
            this.destroy()
        }));
        mxEvent.addListener(a, "selectstart", mxUtils.bind(this,
        function() {
            return this.isEditing()
        }))
    }
};
mxGraph.prototype.createHandlers = function() {
    this.tooltipHandler = new mxTooltipHandler(this);
    this.tooltipHandler.setEnabled(false);
    this.panningHandler = new mxPanningHandler(this);
    this.panningHandler.panningEnabled = false;
    this.selectionCellsHandler = new mxSelectionCellsHandler(this);
    this.connectionHandler = new mxConnectionHandler(this);
    this.connectionHandler.setEnabled(false);
    this.graphHandler = new mxGraphHandler(this)
};
mxGraph.prototype.createSelectionModel = function() {
    return new mxGraphSelectionModel(this)
};
mxGraph.prototype.createStylesheet = function() {
    return new mxStylesheet
};
mxGraph.prototype.createGraphView = function() {
    return new mxGraphView(this)
};
mxGraph.prototype.createCellRenderer = function() {
    return new mxCellRenderer
};
mxGraph.prototype.createCellEditor = function() {
    return new mxCellEditor(this)
};
mxGraph.prototype.getModel = function() {
    return this.model
};
mxGraph.prototype.getView = function() {
    return this.view
};
mxGraph.prototype.getStylesheet = function() {
    return this.stylesheet
};
mxGraph.prototype.setStylesheet = function(a) {
    this.stylesheet = a
};
mxGraph.prototype.getSelectionModel = function() {
    return this.selectionModel
};
mxGraph.prototype.setSelectionModel = function(a) {
    this.selectionModel = a
};
mxGraph.prototype.getSelectionCellsForChanges = function(a) {
    for (var b = [], c = 0; c < a.length; c++) {
        var d = a[c];
        if (d.constructor != mxRootChange) {
            var e = null;
            if (d instanceof mxChildChange && d.previous == null) e = d.child;
            else if (d.cell != null && d.cell instanceof mxCell) e = d.cell;
            e != null && mxUtils.indexOf(b, e) < 0 && b.push(e)
        }
    }
    return this.getModel().getTopmostCells(b)
};
mxGraph.prototype.graphModelChanged = function(a) {
    for (var b = 0; b < a.length; b++) this.processChange(a[b]);
    this.removeSelectionCells(this.getRemovedCellsForChanges(a));
    this.view.validate();
    this.sizeDidChange()
};
mxGraph.prototype.getRemovedCellsForChanges = function(a) {
    for (var b = [], c = 0; c < a.length; c++) {
        var d = a[c];
        if (d instanceof mxRootChange) break;
        else d instanceof mxChildChange ? d.previous != null && d.parent == null && (b = b.concat(this.model.getDescendants(d.child))) : d instanceof mxVisibleChange && (b = b.concat(this.model.getDescendants(d.cell)))
    }
    return b
};
mxGraph.prototype.processChange = function(a) {
    if (a instanceof mxRootChange) {
        this.clearSelection();
        this.removeStateForCell(a.previous);
        if (this.resetViewOnRootChange) {
            this.view.scale = 1;
            this.view.translate.x = 0;
            this.view.translate.y = 0
        }
        this.fireEvent(new mxEventObject(mxEvent.ROOT))
    } else if (a instanceof mxChildChange) {
        var b = this.model.getParent(a.child);
        if (b != null) this.view.invalidate(a.child, true, false, a.previous != null);
        else {
            this.removeStateForCell(a.child);
            this.view.currentRoot == a.child && this.home()
        }
        if (b != a.previous) {
            b != null && this.view.invalidate(b, false, false);
            a.previous != null && this.view.invalidate(a.previous, false, false)
        }
    } else if (a instanceof mxTerminalChange || a instanceof mxGeometryChange) this.view.invalidate(a.cell);
    else if (a instanceof mxValueChange) this.view.invalidate(a.cell, false, false);
    else if (a instanceof mxStyleChange) {
        this.view.invalidate(a.cell, true, true, false);
        this.view.removeState(a.cell)
    } else a.cell != null && a.cell instanceof mxCell && this.removeStateForCell(a.cell)
};
mxGraph.prototype.removeStateForCell = function(a) {
    for (var b = this.model.getChildCount(a), c = 0; c < b; c++) this.removeStateForCell(this.model.getChildAt(a, c));
    this.view.removeState(a)
};
mxGraph.prototype.addCellOverlay = function(a, b) {
    if (a.overlays == null) a.overlays = [];
    a.overlays.push(b);
    var c = this.view.getState(a);
    c != null && this.cellRenderer.redraw(c);
    this.fireEvent(new mxEventObject(mxEvent.ADD_OVERLAY, "cell", a, "overlay", b));
    return b
};
mxGraph.prototype.getCellOverlays = function(a) {
    return a.overlays
};
mxGraph.prototype.removeCellOverlay = function(a, b) {
    if (b == null) this.removeCellOverlays(a);
    else {
        var c = mxUtils.indexOf(a.overlays, b);
        if (c >= 0) {
            a.overlays.splice(c, 1);
            if (a.overlays.length == 0) a.overlays = null;
            c = this.view.getState(a);
            c != null && this.cellRenderer.redraw(c);
            this.fireEvent(new mxEventObject(mxEvent.REMOVE_OVERLAY, "cell", a, "overlay", b))
        } else b = null
    }
    return b
};
mxGraph.prototype.removeCellOverlays = function(a) {
    var b = a.overlays;
    if (b != null) {
        a.overlays = null;
        var c = this.view.getState(a);
        c != null && this.cellRenderer.redraw(c);
        for (c = 0; c < b.length; c++) this.fireEvent(new mxEventObject(mxEvent.REMOVE_OVERLAY, "cell", a, "overlay", b[c]))
    }
    return b
};
mxGraph.prototype.clearCellOverlays = function(a) {
    a = a != null ? a: this.model.getRoot();
    this.removeCellOverlays(a);
    for (var b = this.model.getChildCount(a), c = 0; c < b; c++) this.clearCellOverlays(this.model.getChildAt(a, c))
};
mxGraph.prototype.setCellWarning = function(a, b, c, d) {
    if (b != null && b.length > 0) {
        c = c != null ? c: this.warningImage;
        b = new mxCellOverlay(c, "<font color=red>" + b + "</font>");
        d && b.addListener(mxEvent.CLICK, mxUtils.bind(this,
        function() {
            this.isEnabled() && this.setSelectionCell(a)
        }));
        return this.addCellOverlay(a, b)
    }
    this.removeCellOverlays(a);
    return null
};
mxGraph.prototype.startEditing = function(a) {
    this.startEditingAtCell(null, a)
};
mxGraph.prototype.startEditingAtCell = function(a, b) {
    if (a == null) {
        a = this.getSelectionCell();
        a != null && !this.isCellEditable(a) && (a = null)
    }
    if (a != null) {
        this.fireEvent(new mxEventObject(mxEvent.START_EDITING, "cell", a, "event", b));
        this.cellEditor.startEditing(a, b)
    }
};
mxGraph.prototype.getEditingValue = function(a) {
    return this.convertValueToString(a)
};
mxGraph.prototype.stopEditing = function(a) {
    this.cellEditor.stopEditing(a)
};
mxGraph.prototype.labelChanged = function(a, b, c) {
    this.model.beginUpdate();
    try {
        this.cellLabelChanged(a, b, this.isAutoSizeCell(a));
        this.fireEvent(new mxEventObject(mxEvent.LABEL_CHANGED, "cell", a, "value", b, "event", c))
    } finally {
        this.model.endUpdate()
    }
    return a
};
mxGraph.prototype.cellLabelChanged = function(a, b, c) {
    this.model.beginUpdate();
    try {
        this.model.setValue(a, b);
        c && this.cellSizeUpdated(a, false)
    } finally {
        this.model.endUpdate()
    }
};
mxGraph.prototype.escape = function() {
    this.stopEditing(true);
    this.connectionHandler.reset();
    this.graphHandler.reset();
    for (var a = this.getSelectionCells(), b = 0; b < a.length; b++) {
        var c = this.view.getState(a[b]);
        c != null && c.handler != null && c.handler.reset()
    }
};
mxGraph.prototype.click = function(a) {
    var b = a.getEvent(),
    c = a.getCell(),
    d = new mxEventObject(mxEvent.CLICK, "event", b, "cell", c);
    a.isConsumed() && d.consume();
    this.fireEvent(d);
    if (this.isEnabled() && !mxEvent.isConsumed(b) && !d.isConsumed()) if (c != null) this.selectCellForEvent(c, b);
    else {
        c = null;
        this.isSwimlaneSelectionEnabled() && (c = this.getSwimlaneAt(a.getGraphX(), a.getGraphY()));
        c != null ? this.selectCellForEvent(c, b) : this.isToggleEvent(b) || this.clearSelection()
    }
};
mxGraph.prototype.dblClick = function(a, b) {
    var c = new mxEventObject(mxEvent.DOUBLE_CLICK, "event", a, "cell", b);
    this.fireEvent(c);
    this.isEnabled() && (!mxEvent.isConsumed(a) && !c.isConsumed() && b != null && this.isCellEditable(b)) && this.startEditingAtCell(b, a)
};
mxGraph.prototype.scrollPointToVisible = function(a, b, c, d) {
    if (!this.timerAutoScroll && (this.ignoreScrollbars || mxUtils.hasScrollbars(this.container))) {
        var e = this.container,
        d = d != null ? d: 20;
        if (a >= e.scrollLeft && b >= e.scrollTop && a <= e.scrollLeft + e.clientWidth && b <= e.scrollTop + e.clientHeight) {
            var f = e.scrollLeft + e.clientWidth - a;
            if (f < d) {
                a = e.scrollLeft;
                e.scrollLeft = e.scrollLeft + (d - f);
                if (c && a == e.scrollLeft) {
                    if (this.dialect == mxConstants.DIALECT_SVG) {
                        var a = this.view.getDrawPane().ownerSVGElement,
                        g = this.container.scrollWidth + d - f;
                        a.setAttribute("width", g)
                    } else {
                        g = Math.max(e.clientWidth, e.scrollWidth) + d - f;
                        a = this.view.getCanvas();
                        a.style.width = g + "px"
                    }
                    e.scrollLeft = e.scrollLeft + (d - f)
                }
            } else {
                f = a - e.scrollLeft;
                if (f < d) e.scrollLeft = e.scrollLeft - (d - f)
            }
            f = e.scrollTop + e.clientHeight - b;
            if (f < d) {
                a = e.scrollTop;
                e.scrollTop = e.scrollTop + (d - f);
                if (a == e.scrollTop && c) {
                    if (this.dialect == mxConstants.DIALECT_SVG) {
                        a = this.view.getDrawPane().ownerSVGElement;
                        b = this.container.scrollHeight + d - f;
                        a.setAttribute("height", b)
                    } else {
                        b = Math.max(e.clientHeight, e.scrollHeight) + d - f;
                        a = this.view.getCanvas();
                        a.style.height = b + "px"
                    }
                    e.scrollTop = e.scrollTop + (d - f)
                }
            } else {
                f = b - e.scrollTop;
                if (f < d) e.scrollTop = e.scrollTop - (d - f)
            }
        }
    } else if (this.allowAutoPanning && !this.panningHandler.active) {
        if (this.panningManager == null) this.panningManager = this.createPanningManager();
        this.panningManager.panTo(a + this.panDx, b + this.panDy)
    }
};
mxGraph.prototype.createPanningManager = function() {
    return new mxPanningManager(this)
};
mxGraph.prototype.getBorderSizes = function() {
    function a(a) {
        var b = 0,
        b = a == "thin" ? 2 : a == "medium" ? 4 : a == "thick" ? 6 : parseInt(a);
        isNaN(b) && (b = 0);
        return b
    }
    var b = mxUtils.getCurrentStyle(this.container),
    c = new mxRectangle;
    c.x = a(b.borderLeftWidth) + parseInt(b.paddingLeft || 0);
    c.y = a(b.borderTopWidth) + parseInt(b.paddingTop || 0);
    c.width = a(b.borderRightWidth) + parseInt(b.paddingRight || 0);
    c.height = a(b.borderBottomWidth) + parseInt(b.paddingBottom || 0);
    return c
};
mxGraph.prototype.getPreferredPageSize = function(a, b, c) {
    var a = this.view.scale,
    d = this.view.translate,
    e = this.pageFormat,
    f = a * this.pageScale,
    e = new mxRectangle(0, 0, e.width * f, e.height * f),
    b = this.pageBreaksVisible ? Math.ceil(b / e.width) : 1,
    c = this.pageBreaksVisible ? Math.ceil(c / e.height) : 1;
    return new mxRectangle(0, 0, b * e.width + 2 + d.x / a, c * e.height + 2 + d.y / a)
};
mxGraph.prototype.sizeDidChange = function() {
    var a = this.getGraphBounds();
    if (this.container != null) {
        var b = this.getBorder(),
        c = Math.max(0, a.x + a.width + 1 + b),
        b = Math.max(0, a.y + a.height + 1 + b);
        if (this.minimumContainerSize != null) {
            c = Math.max(c, this.minimumContainerSize.width);
            b = Math.max(b, this.minimumContainerSize.height)
        }
        this.resizeContainer && this.doResizeContainer(c, b);
        if (this.preferPageSize || !mxClient.IS_IE && this.pageVisible) {
            var d = this.getPreferredPageSize(a, c, b);
            if (d != null) {
                c = d.width;
                b = d.height
            }
        }
        if (this.minimumGraphSize != null) {
            c = Math.max(c, this.minimumGraphSize.width * this.view.scale);
            b = Math.max(b, this.minimumGraphSize.height * this.view.scale)
        }
        c = Math.ceil(c - 1);
        b = Math.ceil(b - 1);
        if (this.dialect == mxConstants.DIALECT_SVG) {
            d = this.view.getDrawPane().ownerSVGElement;
            d.style.minWidth = Math.max(1, c) + "px";
            d.style.minHeight = Math.max(1, b) + "px"
        } else if (mxClient.IS_QUIRKS) this.view.updateHtmlCanvasSize(Math.max(1, c), Math.max(1, b));
        else {
            this.view.canvas.style.minWidth = Math.max(1, c) + "px";
            this.view.canvas.style.minHeight = Math.max(1, b) + "px"
        }
        this.updatePageBreaks(this.pageBreaksVisible, c - 1, b - 1)
    }
    this.fireEvent(new mxEventObject(mxEvent.SIZE, "bounds", a))
};
mxGraph.prototype.doResizeContainer = function(a, b) {
    if (mxClient.IS_IE) if (mxClient.IS_QUIRKS) var c = this.getBorderSizes(),
    a = a + Math.max(2, c.x + c.width + 1),
    b = b + Math.max(2, c.y + c.height + 1);
    else if (document.documentMode >= 9) {
        a = a + 3;
        b = b + 5
    } else {
        a = a + 1;
        b = b + 1
    } else b = b + 1;
    if (this.maximumContainerSize != null) {
        a = Math.min(this.maximumContainerSize.width, a);
        b = Math.min(this.maximumContainerSize.height, b)
    }
    this.container.style.width = Math.ceil(a) + "px";
    this.container.style.height = Math.ceil(b) + "px"
};
mxGraph.prototype.updatePageBreaks = function(a, b, c) {
    var d = this.view.scale,
    e = this.view.translate,
    f = this.pageFormat,
    g = d * this.pageScale,
    e = new mxRectangle(d * e.x, d * e.y, f.width * g, f.height * g),
    a = a && Math.min(e.width, e.height) > this.minPageBreakDist;
    e.x = mxUtils.mod(e.x, e.width);
    e.y = mxUtils.mod(e.y, e.height);
    f = a ? Math.ceil((b - e.x) / e.width) : 0;
    a = a ? Math.ceil((c - e.y) / e.height) : 0;
    if (this.horizontalPageBreaks == null && f > 0) this.horizontalPageBreaks = [];
    if (this.horizontalPageBreaks != null) {
        for (g = 0; g <= f; g++) {
            var h = [new mxPoint(e.x + g * e.width, 1), new mxPoint(e.x + g * e.width, c)];
            if (this.horizontalPageBreaks[g] != null) {
                this.horizontalPageBreaks[g].scale = 1;
                this.horizontalPageBreaks[g].points = h;
                this.horizontalPageBreaks[g].redraw()
            } else {
                h = new mxPolyline(h, this.pageBreakColor, this.scale);
                h.dialect = this.dialect;
                h.isDashed = this.pageBreakDashed;
                h.scale = d;
                h.crisp = true;
                h.init(this.view.backgroundPane);
                h.redraw();
                this.horizontalPageBreaks[g] = h
            }
        }
        for (g = f; g < this.horizontalPageBreaks.length; g++) this.horizontalPageBreaks[g].destroy();
        this.horizontalPageBreaks.splice(f, this.horizontalPageBreaks.length - f)
    }
    if (this.verticalPageBreaks == null && a > 0) this.verticalPageBreaks = [];
    if (this.verticalPageBreaks != null) {
        for (g = 0; g <= a; g++) {
            h = [new mxPoint(1, e.y + g * e.height), new mxPoint(b, e.y + g * e.height)];
            if (this.verticalPageBreaks[g] != null) {
                this.verticalPageBreaks[g].scale = 1;
                this.verticalPageBreaks[g].points = h;
                this.verticalPageBreaks[g].redraw()
            } else {
                h = new mxPolyline(h, this.pageBreakColor, d);
                h.dialect = this.dialect;
                h.isDashed = this.pageBreakDashed;
                h.scale = d;
                h.crisp = true;
                h.init(this.view.backgroundPane);
                h.redraw();
                this.verticalPageBreaks[g] = h
            }
        }
        for (g = a; g < this.verticalPageBreaks.length; g++) this.verticalPageBreaks[g].destroy();
        this.verticalPageBreaks.splice(a, this.verticalPageBreaks.length - a)
    }
};
mxGraph.prototype.getCellStyle = function(a) {
    var b = this.model.getStyle(a),
    c = null,
    c = this.model.isEdge(a) ? this.stylesheet.getDefaultEdgeStyle() : this.stylesheet.getDefaultVertexStyle();
    b != null && (c = this.postProcessCellStyle(this.stylesheet.getCellStyle(b, c)));
    if (c == null) c = mxGraph.prototype.EMPTY_ARRAY;
    return c
};
mxGraph.prototype.postProcessCellStyle = function(a) {
    if (a != null) {
        var b = a[mxConstants.STYLE_IMAGE],
        c = this.getImageFromBundles(b);
        c != null ? a[mxConstants.STYLE_IMAGE] = c: c = b;
        if (c != null && c.substring(0, 11) == "data:image/") {
            b = c.indexOf(",");
            b > 0 && (c = c.substring(0, b) + ";base64," + c.substring(b + 1));
            a[mxConstants.STYLE_IMAGE] = c
        }
    }
    return a
};
mxGraph.prototype.setCellStyle = function(a, b) {
    b = b || this.getSelectionCells();
    if (b != null) {
        this.model.beginUpdate();
        try {
            for (var c = 0; c < b.length; c++) this.model.setStyle(b[c], a)
        } finally {
            this.model.endUpdate()
        }
    }
};
mxGraph.prototype.toggleCellStyle = function(a, b, c) {
    c = c || this.getSelectionCell();
    this.toggleCellStyles(a, b, [c])
};
mxGraph.prototype.toggleCellStyles = function(a, b, c) {
    b = b != null ? b: false;
    c = c || this.getSelectionCells();
    if (c != null && c.length > 0) {
        var d = this.view.getState(c[0]),
        d = d != null ? d.style: this.getCellStyle(c[0]);
        if (d != null) {
            b = mxUtils.getValue(d, a, b) ? 0 : 1;
            this.setCellStyles(a, b, c)
        }
    }
};
mxGraph.prototype.setCellStyles = function(a, b, c) {
    c = c || this.getSelectionCells();
    mxUtils.setCellStyles(this.model, c, a, b)
};
mxGraph.prototype.toggleCellStyleFlags = function(a, b, c) {
    this.setCellStyleFlags(a, b, null, c)
};
mxGraph.prototype.setCellStyleFlags = function(a, b, c, d) {
    d = d || this.getSelectionCells();
    if (d != null && d.length > 0) {
        if (c == null) {
            var e = this.view.getState(d[0]),
            e = e != null ? e.style: this.getCellStyle(d[0]);
            e != null && (c = (parseInt(e[a] || 0) & b) != b)
        }
        mxUtils.setCellStyleFlags(this.model, d, a, b, c)
    }
};
mxGraph.prototype.alignCells = function(a, b, c) {
    b == null && (b = this.getSelectionCells());
    if (b != null && b.length > 1) {
        if (c == null) for (var d = 0; d < b.length; d++) {
            var e = this.getCellGeometry(b[d]);
            if (e != null && !this.model.isEdge(b[d])) if (c == null) if (a == mxConstants.ALIGN_CENTER) {
                c = e.x + e.width / 2;
                break
            } else if (a == mxConstants.ALIGN_RIGHT) c = e.x + e.width;
            else if (a == mxConstants.ALIGN_TOP) c = e.y;
            else if (a == mxConstants.ALIGN_MIDDLE) {
                c = e.y + e.height / 2;
                break
            } else c = a == mxConstants.ALIGN_BOTTOM ? e.y + e.height: e.x;
            else c = a == mxConstants.ALIGN_RIGHT ? Math.max(c, e.x + e.width) : a == mxConstants.ALIGN_TOP ? Math.min(c, e.y) : a == mxConstants.ALIGN_BOTTOM ? Math.max(c, e.y + e.height) : Math.min(c, e.x)
        }
        if (c != null) {
            this.model.beginUpdate();
            try {
                for (d = 0; d < b.length; d++) {
                    e = this.getCellGeometry(b[d]);
                    if (e != null && !this.model.isEdge(b[d])) {
                        e = e.clone();
                        a == mxConstants.ALIGN_CENTER ? e.x = c - e.width / 2 : a == mxConstants.ALIGN_RIGHT ? e.x = c - e.width: a == mxConstants.ALIGN_TOP ? e.y = c: a == mxConstants.ALIGN_MIDDLE ? e.y = c - e.height / 2 : a == mxConstants.ALIGN_BOTTOM ? e.y = c - e.height: e.x = c;
                        this.model.setGeometry(b[d], e)
                    }
                }
                this.fireEvent(new mxEventObject(mxEvent.ALIGN_CELLS, "align", a, "cells", b))
            } finally {
                this.model.endUpdate()
            }
        }
    }
    return b
};
mxGraph.prototype.flipEdge = function(a) {
    if (a != null && this.alternateEdgeStyle != null) {
        this.model.beginUpdate();
        try {
            var b = this.model.getStyle(a);
            b == null || b.length == 0 ? this.model.setStyle(a, this.alternateEdgeStyle) : this.model.setStyle(a, null);
            this.resetEdge(a);
            this.fireEvent(new mxEventObject(mxEvent.FLIP_EDGE, "edge", a))
        } finally {
            this.model.endUpdate()
        }
    }
    return a
};
mxGraph.prototype.addImageBundle = function(a) {
    this.imageBundles.push(a)
};
mxGraph.prototype.removeImageBundle = function(a) {
    for (var b = [], c = 0; c < this.imageBundles.length; c++) this.imageBundles[c] != a && b.push(this.imageBundles[c]);
    this.imageBundles = b
};
mxGraph.prototype.getImageFromBundles = function(a) {
    if (a != null) for (var b = 0; b < this.imageBundles.length; b++) {
        var c = this.imageBundles[b].getImage(a);
        if (c != null) return c
    }
    return null
};
mxGraph.prototype.orderCells = function(a, b) {
    b == null && (b = mxUtils.sortCells(this.getSelectionCells(), true));
    this.model.beginUpdate();
    try {
        this.cellsOrdered(b, a);
        this.fireEvent(new mxEventObject(mxEvent.ORDER_CELLS, "back", a, "cells", b))
    } finally {
        this.model.endUpdate()
    }
    return b
};
mxGraph.prototype.cellsOrdered = function(a, b) {
    if (a != null) {
        this.model.beginUpdate();
        try {
            for (var c = 0; c < a.length; c++) {
                var d = this.model.getParent(a[c]);
                b ? this.model.add(d, a[c], c) : this.model.add(d, a[c], this.model.getChildCount(d) - 1)
            }
            this.fireEvent(new mxEventObject(mxEvent.CELLS_ORDERED, "back", b, "cells", a))
        } finally {
            this.model.endUpdate()
        }
    }
};
mxGraph.prototype.groupCells = function(a, b, c) {
    c == null && (c = mxUtils.sortCells(this.getSelectionCells(), true));
    c = this.getCellsForGroup(c);
    a == null && (a = this.createGroupCell(c));
    var d = this.getBoundsForGroup(a, c, b);
    if (c.length > 0 && d != null) {
        var e = this.model.getParent(a);
        e == null && (e = this.model.getParent(c[0]));
        this.model.beginUpdate();
        try {
            this.getCellGeometry(a) == null && this.model.setGeometry(a, new mxGeometry);
            var f = this.model.getChildCount(a);
            this.cellsAdded(c, a, f, null, null, false, false);
            this.cellsMoved(c, -d.x, -d.y, false, true);
            f = this.model.getChildCount(e);
            this.cellsAdded([a], e, f, null, null, false);
            this.cellsResized([a], [d]);
            this.fireEvent(new mxEventObject(mxEvent.GROUP_CELLS, "group", a, "border", b, "cells", c))
        } finally {
            this.model.endUpdate()
        }
    }
    return a
};
mxGraph.prototype.getCellsForGroup = function(a) {
    var b = [];
    if (a != null && a.length > 0) {
        var c = this.model.getParent(a[0]);
        b.push(a[0]);
        for (var d = 1; d < a.length; d++) this.model.getParent(a[d]) == c && b.push(a[d])
    }
    return b
};
mxGraph.prototype.getBoundsForGroup = function(a, b, c) {
    b = this.getBoundingBoxFromGeometry(b);
    if (b != null) {
        if (this.isSwimlane(a)) {
            a = this.getStartSize(a);
            b.x = b.x - a.width;
            b.y = b.y - a.height;
            b.width = b.width + a.width;
            b.height = b.height + a.height
        }
        b.x = b.x - c;
        b.y = b.y - c;
        b.width = b.width + 2 * c;
        b.height = b.height + 2 * c
    }
    return b
};
mxGraph.prototype.createGroupCell = function() {
    var a = new mxCell("");
    a.setVertex(true);
    a.setConnectable(false);
    return a
};
mxGraph.prototype.ungroupCells = function(a) {
    var b = [];
    if (a == null) {
        for (var a = this.getSelectionCells(), c = [], d = 0; d < a.length; d++) this.model.getChildCount(a[d]) > 0 && c.push(a[d]);
        a = c
    }
    if (a != null && a.length > 0) {
        this.model.beginUpdate();
        try {
            for (d = 0; d < a.length; d++) {
                var e = this.model.getChildren(a[d]);
                if (e != null && e.length > 0) {
                    var e = e.slice(),
                    f = this.model.getParent(a[d]),
                    g = this.model.getChildCount(f);
                    this.cellsAdded(e, f, g, null, null, true);
                    b = b.concat(e)
                }
            }
            this.cellsRemoved(this.addAllEdges(a));
            this.fireEvent(new mxEventObject(mxEvent.UNGROUP_CELLS, "cells", a))
        } finally {
            this.model.endUpdate()
        }
    }
    return b
};
mxGraph.prototype.removeCellsFromParent = function(a) {
    a == null && (a = this.getSelectionCells());
    this.model.beginUpdate();
    try {
        var b = this.getDefaultParent(),
        c = this.model.getChildCount(b);
        this.cellsAdded(a, b, c, null, null, true);
        this.fireEvent(new mxEventObject(mxEvent.REMOVE_CELLS_FROM_PARENT, "cells", a))
    } finally {
        this.model.endUpdate()
    }
    return a
};
mxGraph.prototype.updateGroupBounds = function(a, b, c) {
    a == null && (a = this.getSelectionCells());
    b = b != null ? b: 0;
    c = c != null ? c: false;
    this.model.beginUpdate();
    try {
        for (var d = 0; d < a.length; d++) {
            var e = this.getCellGeometry(a[d]);
            if (e != null) {
                var f = this.getChildCells(a[d]);
                if (f != null && f.length > 0) {
                    var g = this.getBoundingBoxFromGeometry(f);
                    if (g.width > 0 && g.height > 0) {
                        var h = this.isSwimlane(a[d]) ? this.getStartSize(a[d]) : new mxRectangle,
                        e = e.clone();
                        if (c) {
                            e.x = e.x + (g.x - h.width - b);
                            e.y = e.y + (g.y - h.height - b)
                        }
                        e.width = g.width + h.width + 2 * b;
                        e.height = g.height + h.height + 2 * b;
                        this.model.setGeometry(a[d], e);
                        this.moveCells(f, -g.x + h.width + b, -g.y + h.height + b)
                    }
                }
            }
        }
    } finally {
        this.model.endUpdate()
    }
    return a
};
mxGraph.prototype.cloneCells = function(a, b) {
    var b = b != null ? b: true,
    c = null;
    if (a != null) {
        for (var d = {},
        c = [], e = 0; e < a.length; e++) {
            var f = mxCellPath.create(a[e]);
            d[f] = a[e];
            c.push(a[e])
        }
        if (c.length > 0) for (var f = this.view.scale,
        g = this.view.translate,
        c = this.model.cloneCells(a, true), e = 0; e < a.length; e++) if (!b && this.model.isEdge(c[e]) && this.getEdgeValidationError(c[e], this.model.getTerminal(c[e], true), this.model.getTerminal(c[e], false)) != null) c[e] = null;
        else {
            var h = this.model.getGeometry(c[e]);
            if (h != null) {
                var k = this.view.getState(a[e]),
                i = this.view.getState(this.model.getParent(a[e]));
                if (k != null && i != null) {
                    var l = i.origin.x,
                    i = i.origin.y;
                    if (this.model.isEdge(c[e])) {
                        for (var k = k.absolutePoints,
                        m = this.model.getTerminal(a[e], true), n = mxCellPath.create(m); m != null && d[n] == null;) {
                            m = this.model.getParent(m);
                            n = mxCellPath.create(m)
                        }
                        m == null && h.setTerminalPoint(new mxPoint(k[0].x / f - g.x, k[0].y / f - g.y), true);
                        m = this.model.getTerminal(a[e], false);
                        for (n = mxCellPath.create(m); m != null && d[n] == null;) {
                            m = this.model.getParent(m);
                            n = mxCellPath.create(m)
                        }
                        if (m == null) {
                            m = k.length - 1;
                            h.setTerminalPoint(new mxPoint(k[m].x / f - g.x, k[m].y / f - g.y), false)
                        }
                        h = h.points;
                        if (h != null) for (k = 0; k < h.length; k++) {
                            h[k].x = h[k].x + l;
                            h[k].y = h[k].y + i
                        }
                    } else {
                        h.x = h.x + l;
                        h.y = h.y + i
                    }
                }
            }
        } else c = []
    }
    return c
};
mxGraph.prototype.insertVertex = function(a, b, c, d, e, f, g, h, k) {
    return this.addCell(this.createVertex(a, b, c, d, e, f, g, h, k), a)
};
mxGraph.prototype.createVertex = function(a, b, c, d, e, f, g, h, k) {
    a = new mxGeometry(d, e, f, g);
    a.relative = k != null ? k: false;
    c = new mxCell(c, a, h);
    c.setId(b);
    c.setVertex(true);
    c.setConnectable(true);
    return c
};
mxGraph.prototype.insertEdge = function(a, b, c, d, e, f) {
    return this.addEdge(this.createEdge(a, b, c, d, e, f), a, d, e)
};
mxGraph.prototype.createEdge = function(a, b, c, d, e, f) {
    a = new mxCell(c, new mxGeometry, f);
    a.setId(b);
    a.setEdge(true);
    a.geometry.relative = true;
    return a
};
mxGraph.prototype.addEdge = function(a, b, c, d, e) {
    return this.addCell(a, b, e, c, d)
};
mxGraph.prototype.addCell = function(a, b, c, d, e) {
    return this.addCells([a], b, c, d, e)[0]
};
mxGraph.prototype.addCells = function(a, b, c, d, e) {
    b == null && (b = this.getDefaultParent());
    c == null && (c = this.model.getChildCount(b));
    this.model.beginUpdate();
    try {
        this.cellsAdded(a, b, c, d, e, false, true);
        this.fireEvent(new mxEventObject(mxEvent.ADD_CELLS, "cells", a, "parent", b, "index", c, "source", d, "target", e))
    } finally {
        this.model.endUpdate()
    }
    return a
};
mxGraph.prototype.cellsAdded = function(a, b, c, d, e, f, g) {
    if (a != null && b != null && c != null) {
        this.model.beginUpdate();
        try {
            for (var h = f ? this.view.getState(b) : null, k = h != null ? h.origin: null, i = new mxPoint(0, 0), h = 0; h < a.length; h++) if (a[h] == null) c--;
            else {
                var l = this.model.getParent(a[h]);
                if (k != null && a[h] != b && b != l) {
                    var m = this.view.getState(l),
                    n = m != null ? m.origin: i,
                    o = this.model.getGeometry(a[h]);
                    if (o != null) {
                        var p = n.x - k.x,
                        q = n.y - k.y,
                        o = o.clone();
                        o.translate(p, q);
                        if (!o.relative && this.model.isVertex(a[h]) && !this.isAllowNegativeCoordinates()) {
                            o.x = Math.max(0, o.x);
                            o.y = Math.max(0, o.y)
                        }
                        this.model.setGeometry(a[h], o)
                    }
                }
                b == l && c--;
                this.model.add(b, a[h], c + h);
                this.isExtendParentsOnAdd() && this.isExtendParent(a[h]) && this.extendParent(a[h]); (g == null || g) && this.constrainChild(a[h]);
                d != null && this.cellConnected(a[h], d, true);
                e != null && this.cellConnected(a[h], e, false)
            }
            this.fireEvent(new mxEventObject(mxEvent.CELLS_ADDED, "cells", a, "parent", b, "index", c, "source", d, "target", e, "absolute", f))
        } finally {
            this.model.endUpdate()
        }
    }
};
mxGraph.prototype.removeCells = function(a, b) {
    b = b != null ? b: true;
    a == null && (a = this.getDeletableCells(this.getSelectionCells()));
    b && (a = this.getDeletableCells(this.addAllEdges(a)));
    this.model.beginUpdate();
    try {
        this.cellsRemoved(a);
        this.fireEvent(new mxEventObject(mxEvent.REMOVE_CELLS, "cells", a, "includeEdges", b))
    } finally {
        this.model.endUpdate()
    }
    return a
};
mxGraph.prototype.cellsRemoved = function(a) {
    if (a != null && a.length > 0) {
        var b = this.view.scale,
        c = this.view.translate;
        this.model.beginUpdate();
        try {
            for (var d = {},
            e = 0; e < a.length; e++) {
                var f = mxCellPath.create(a[e]);
                d[f] = a[e]
            }
            for (e = 0; e < a.length; e++) {
                for (var g = this.getConnections(a[e]), h = 0; h < g.length; h++) {
                    f = mxCellPath.create(g[h]);
                    if (d[f] == null) {
                        var k = this.model.getGeometry(g[h]);
                        if (k != null) {
                            var i = this.view.getState(g[h]);
                            if (i != null) {
                                var k = k.clone(),
                                l = i.getVisibleTerminal(true) == a[e],
                                m = i.absolutePoints,
                                n = l ? 0 : m.length - 1;
                                k.setTerminalPoint(new mxPoint(m[n].x / b - c.x, m[n].y / b - c.y), l);
                                this.model.setTerminal(g[h], null, l);
                                this.model.setGeometry(g[h], k)
                            }
                        }
                    }
                }
                this.model.remove(a[e])
            }
            this.fireEvent(new mxEventObject(mxEvent.CELLS_REMOVED, "cells", a))
        } finally {
            this.model.endUpdate()
        }
    }
};
mxGraph.prototype.splitEdge = function(a, b, c, d, e) {
    d = d || 0;
    e = e || 0;
    c == null && (c = this.cloneCells([a])[0]);
    var f = this.model.getParent(a),
    g = this.model.getTerminal(a, true);
    this.model.beginUpdate();
    try {
        this.cellsMoved(b, d, e, false, false);
        this.cellsAdded(b, f, this.model.getChildCount(f), null, null, true);
        this.cellsAdded([c], f, this.model.getChildCount(f), g, b[0], false);
        this.cellConnected(a, b[0], true);
        this.fireEvent(new mxEventObject(mxEvent.SPLIT_EDGE, "edge", a, "cells", b, "newEdge", c, "dx", d, "dy", e))
    } finally {
        this.model.endUpdate()
    }
    return c
};
mxGraph.prototype.toggleCells = function(a, b, c) {
    b == null && (b = this.getSelectionCells());
    c && (b = this.addAllEdges(b));
    this.model.beginUpdate();
    try {
        this.cellsToggled(b, a);
        this.fireEvent(new mxEventObject(mxEvent.TOGGLE_CELLS, "show", a, "cells", b, "includeEdges", c))
    } finally {
        this.model.endUpdate()
    }
    return b
};
mxGraph.prototype.cellsToggled = function(a, b) {
    if (a != null && a.length > 0) {
        this.model.beginUpdate();
        try {
            for (var c = 0; c < a.length; c++) this.model.setVisible(a[c], b)
        } finally {
            this.model.endUpdate()
        }
    }
};
mxGraph.prototype.foldCells = function(a, b, c, d) {
    b = b != null ? b: false;
    c == null && (c = this.getFoldableCells(this.getSelectionCells(), a));
    this.stopEditing(false);
    this.model.beginUpdate();
    try {
        this.cellsFolded(c, a, b, d);
        this.fireEvent(new mxEventObject(mxEvent.FOLD_CELLS, "collapse", a, "recurse", b, "cells", c))
    } finally {
        this.model.endUpdate()
    }
    return c
};
mxGraph.prototype.cellsFolded = function(a, b, c, d) {
    if (a != null && a.length > 0) {
        this.model.beginUpdate();
        try {
            for (var e = 0; e < a.length; e++) if ((!d || this.isCellFoldable(a[e], b)) && b != this.isCellCollapsed(a[e])) {
                this.model.setCollapsed(a[e], b);
                this.swapBounds(a[e], b);
                this.isExtendParent(a[e]) && this.extendParent(a[e]);
                c && this.foldCells(this.model.getChildren(a[e]), b, c)
            }
            this.fireEvent(new mxEventObject(mxEvent.CELLS_FOLDED, "cells", a, "collapse", b, "recurse", c))
        } finally {
            this.model.endUpdate()
        }
    }
};
mxGraph.prototype.swapBounds = function(a, b) {
    if (a != null) {
        var c = this.model.getGeometry(a);
        if (c != null) {
            c = c.clone();
            this.updateAlternateBounds(a, c, b);
            c.swap();
            this.model.setGeometry(a, c)
        }
    }
};
mxGraph.prototype.updateAlternateBounds = function(a, b) {
    if (a != null && b != null) if (b.alternateBounds == null) {
        var c = b;
        if (this.collapseToPreferredSize) {
            var d = this.getPreferredSizeForCell(a);
            if (d != null) {
                c = d;
                d = this.view.getState(a);
                d = d != null ? d.style: this.getCellStyle(a);
                d = mxUtils.getValue(d, mxConstants.STYLE_STARTSIZE);
                if (d > 0) c.height = Math.max(c.height, d)
            }
        }
        b.alternateBounds = new mxRectangle(b.x, b.y, c.width, c.height)
    } else {
        b.alternateBounds.x = b.x;
        b.alternateBounds.y = b.y
    }
};
mxGraph.prototype.addAllEdges = function(a) {
    var b = a.slice();
    return b = b.concat(this.getAllEdges(a))
};
mxGraph.prototype.getAllEdges = function(a) {
    var b = [];
    if (a != null) for (var c = 0; c < a.length; c++) {
        for (var d = this.model.getEdgeCount(a[c]), e = 0; e < d; e++) b.push(this.model.getEdgeAt(a[c], e));
        d = this.model.getChildren(a[c]);
        b = b.concat(this.getAllEdges(d))
    }
    return b
};
mxGraph.prototype.updateCellSize = function(a, b) {
    b = b != null ? b: false;
    this.model.beginUpdate();
    try {
        this.cellSizeUpdated(a, b);
        this.fireEvent(new mxEventObject(mxEvent.UPDATE_CELL_SIZE, "cell", a, "ignoreChildren", b))
    } finally {
        this.model.endUpdate()
    }
    return a
};
mxGraph.prototype.cellSizeUpdated = function(a, b) {
    if (a != null) {
        this.model.beginUpdate();
        try {
            var c = this.getPreferredSizeForCell(a),
            d = this.model.getGeometry(a);
            if (c != null && d != null) {
                var e = this.isCellCollapsed(a),
                d = d.clone();
                if (this.isSwimlane(a)) {
                    var f = this.view.getState(a),
                    g = f != null ? f.style: this.getCellStyle(a),
                    h = this.model.getStyle(a);
                    h == null && (h = "");
                    if (mxUtils.getValue(g, mxConstants.STYLE_HORIZONTAL, true)) {
                        h = mxUtils.setStyle(h, mxConstants.STYLE_STARTSIZE, c.height + 8);
                        if (e) d.height = c.height + 8;
                        d.width = c.width
                    } else {
                        h = mxUtils.setStyle(h, mxConstants.STYLE_STARTSIZE, c.width + 8);
                        if (e) d.width = c.width + 8;
                        d.height = c.height
                    }
                    this.model.setStyle(a, h)
                } else {
                    d.width = c.width;
                    d.height = c.height
                }
                if (!b && !e) {
                    var k = this.view.getBounds(this.model.getChildren(a));
                    if (k != null) {
                        var i = this.view.translate,
                        l = this.view.scale,
                        m = (k.y + k.height) / l - d.y - i.y;
                        d.width = Math.max(d.width, (k.x + k.width) / l - d.x - i.x);
                        d.height = Math.max(d.height, m)
                    }
                }
                this.cellsResized([a], [d])
            }
        } finally {
            this.model.endUpdate()
        }
    }
};
mxGraph.prototype.getPreferredSizeForCell = function(a) {
    var b = null;
    if (a != null) {
        var c = this.view.getState(a),
        d = c != null ? c.style: this.getCellStyle(a);
        if (d != null && !this.model.isEdge(a)) {
            var e = d[mxConstants.STYLE_FONTSIZE] || mxConstants.DEFAULT_FONTSIZE,
            f = 0,
            b = 0;
            if ((this.getImage(c) != null || d[mxConstants.STYLE_IMAGE] != null) && d[mxConstants.STYLE_SHAPE] == mxConstants.SHAPE_LABEL) {
                d[mxConstants.STYLE_VERTICAL_ALIGN] == mxConstants.ALIGN_MIDDLE && (f = f + (parseFloat(d[mxConstants.STYLE_IMAGE_WIDTH]) || mxLabel.prototype.imageSize));
                d[mxConstants.STYLE_ALIGN] != mxConstants.ALIGN_CENTER && (b = b + (parseFloat(d[mxConstants.STYLE_IMAGE_HEIGHT]) || mxLabel.prototype.imageSize))
            }
            f = f + 2 * (d[mxConstants.STYLE_SPACING] || 0);
            f = f + (d[mxConstants.STYLE_SPACING_LEFT] || 0);
            f = f + (d[mxConstants.STYLE_SPACING_RIGHT] || 0);
            b = b + 2 * (d[mxConstants.STYLE_SPACING] || 0);
            b = b + (d[mxConstants.STYLE_SPACING_TOP] || 0);
            b = b + (d[mxConstants.STYLE_SPACING_BOTTOM] || 0);
            c = this.getFoldingImage(c);
            c != null && (f = f + (c.width + 8));
            c = this.getLabel(a);
            if (c != null && c.length > 0) {
                this.isHtmlLabel(a) || (c = c.replace(/\n/g, "<br>"));
                e = mxUtils.getSizeForString(c, e, d[mxConstants.STYLE_FONTFAMILY]);
                a = e.width + f;
                b = e.height + b;
                if (!mxUtils.getValue(d, mxConstants.STYLE_HORIZONTAL, true)) {
                    d = b;
                    b = a;
                    a = d
                }
                if (this.gridEnabled) {
                    a = this.snap(a + this.gridSize / 2);
                    b = this.snap(b + this.gridSize / 2)
                }
                b = new mxRectangle(0, 0, a, b)
            } else {
                d = 4 * this.gridSize;
                b = new mxRectangle(0, 0, d, d)
            }
        }
    }
    return b
};
mxGraph.prototype.handleGesture = function(a, b) {
    if (Math.abs(1 - b.scale) > 0.2) {
        var c = this.view.scale,
        d = this.view.translate,
        e = a.width * b.scale,
        f = a.height * b.scale,
        g = a.y - (f - a.height) / 2,
        c = new mxRectangle(this.snap((a.x - (e - a.width) / 2) / c) - d.x, this.snap(g / c) - d.y, this.snap(e / c), this.snap(f / c));
        this.resizeCell(a.cell, c)
    }
};
mxGraph.prototype.resizeCell = function(a, b) {
    return this.resizeCells([a], [b])[0]
};
mxGraph.prototype.resizeCells = function(a, b) {
    this.model.beginUpdate();
    try {
        this.cellsResized(a, b);
        this.fireEvent(new mxEventObject(mxEvent.RESIZE_CELLS, "cells", a, "bounds", b))
    } finally {
        this.model.endUpdate()
    }
    return a
};
mxGraph.prototype.cellsResized = function(a, b) {
    if (a != null && b != null && a.length == b.length) {
        this.model.beginUpdate();
        try {
            for (var c = 0; c < a.length; c++) {
                var d = b[c],
                e = this.model.getGeometry(a[c]);
                if (e != null && (e.x != d.x || e.y != d.y || e.width != d.width || e.height != d.height)) {
                    e = e.clone();
                    if (e.relative) {
                        var f = e.offset;
                        if (f != null) {
                            f.x = f.x + (d.x - e.x);
                            f.y = f.y + (d.y - e.y)
                        }
                    } else {
                        e.x = d.x;
                        e.y = d.y
                    }
                    e.width = d.width;
                    e.height = d.height;
                    if (!e.relative && this.model.isVertex(a[c]) && !this.isAllowNegativeCoordinates()) {
                        e.x = Math.max(0, e.x);
                        e.y = Math.max(0, e.y)
                    }
                    this.model.setGeometry(a[c], e);
                    this.isExtendParent(a[c]) && this.extendParent(a[c])
                }
            }
            this.resetEdgesOnResize && this.resetEdges(a);
            this.fireEvent(new mxEventObject(mxEvent.CELLS_RESIZED, "cells", a, "bounds", b))
        } finally {
            this.model.endUpdate()
        }
    }
};
mxGraph.prototype.extendParent = function(a) {
    if (a != null) {
        var b = this.model.getParent(a),
        c = this.model.getGeometry(b);
        if (b != null && c != null && !this.isCellCollapsed(b)) {
            a = this.model.getGeometry(a);
            if (a != null && (c.width < a.x + a.width || c.height < a.y + a.height)) {
                c = c.clone();
                c.width = Math.max(c.width, a.x + a.width);
                c.height = Math.max(c.height, a.y + a.height);
                this.cellsResized([b], [c])
            }
        }
    }
};
mxGraph.prototype.importCells = function(a, b, c, d, e) {
    return this.moveCells(a, b, c, true, d, e)
};
mxGraph.prototype.moveCells = function(a, b, c, d, e, f) {
    b = b != null ? b: 0;
    c = c != null ? c: 0;
    d = d != null ? d: false;
    if (a != null && (b != 0 || c != 0 || d || e != null)) {
        this.model.beginUpdate();
        try {
            if (d) {
                a = this.cloneCells(a, this.isCloneInvalidEdges());
                e == null && (e = this.getDefaultParent())
            }
            var g = this.isAllowNegativeCoordinates();
            e != null && this.setAllowNegativeCoordinates(true);
            this.cellsMoved(a, b, c, !d && this.isDisconnectOnMove() && this.isAllowDanglingEdges(), e == null);
            this.setAllowNegativeCoordinates(g);
            if (e != null) {
                var h = this.model.getChildCount(e);
                this.cellsAdded(a, e, h, null, null, true)
            }
            this.fireEvent(new mxEventObject(mxEvent.MOVE_CELLS, "cells", a, "dx", b, "dy", c, "clone", d, "target", e, "event", f))
        } finally {
            this.model.endUpdate()
        }
    }
    return a
};
mxGraph.prototype.cellsMoved = function(a, b, c, d, e) {
    if (a != null && (b != 0 || c != 0)) {
        this.model.beginUpdate();
        try {
            d && this.disconnectGraph(a);
            for (var f = 0; f < a.length; f++) {
                this.translateCell(a[f], b, c);
                e && this.constrainChild(a[f])
            }
            this.resetEdgesOnMove && this.resetEdges(a);
            this.fireEvent(new mxEventObject(mxEvent.CELLS_MOVED, "cells", a, "dx", c, "dy", c, "disconnect", d))
        } finally {
            this.model.endUpdate()
        }
    }
};
mxGraph.prototype.translateCell = function(a, b, c) {
    var d = this.model.getGeometry(a);
    if (d != null) {
        d = d.clone();
        d.translate(b, c);
        if (!d.relative && this.model.isVertex(a) && !this.isAllowNegativeCoordinates()) {
            d.x = Math.max(0, d.x);
            d.y = Math.max(0, d.y)
        }
        if (d.relative && !this.model.isEdge(a)) if (d.offset == null) d.offset = new mxPoint(b, c);
        else {
            d.offset.x = d.offset.x + b;
            d.offset.y = d.offset.y + c
        }
        this.model.setGeometry(a, d)
    }
};
mxGraph.prototype.getCellContainmentArea = function(a) {
    if (a != null && !this.model.isEdge(a)) {
        var b = this.model.getParent(a);
        if (b == this.getDefaultParent() || b == this.getCurrentRoot()) return this.getMaximumGraphBounds();
        if (b != null && b != this.getDefaultParent()) {
            var c = this.model.getGeometry(b);
            if (c != null) {
                var d = a = 0,
                e = c.width,
                c = c.height;
                if (this.isSwimlane(b)) {
                    b = this.getStartSize(b);
                    a = b.width;
                    e = e - b.width;
                    d = b.height;
                    c = c - b.height
                }
                return new mxRectangle(a, d, e, c)
            }
        }
    }
    return null
};
mxGraph.prototype.getMaximumGraphBounds = function() {
    return this.maximumGraphBounds
};
mxGraph.prototype.constrainChild = function(a) {
    if (a != null) {
        var b = this.model.getGeometry(a),
        c = this.isConstrainChild(a) ? this.getCellContainmentArea(a) : this.getMaximumGraphBounds();
        if (b != null && c != null && !b.relative && (b.x < c.x || b.y < c.y || c.width < b.x + b.width || c.height < b.y + b.height)) {
            a = this.getOverlap(a);
            if (c.width > 0) b.x = Math.min(b.x, c.x + c.width - (1 - a) * b.width);
            if (c.height > 0) b.y = Math.min(b.y, c.y + c.height - (1 - a) * b.height);
            b.x = Math.max(b.x, c.x - b.width * a);
            b.y = Math.max(b.y, c.y - b.height * a)
        }
    }
};
mxGraph.prototype.resetEdges = function(a) {
    if (a != null) {
        for (var b = {},
        c = 0; c < a.length; c++) {
            var d = mxCellPath.create(a[c]);
            b[d] = a[c]
        }
        this.model.beginUpdate();
        try {
            for (c = 0; c < a.length; c++) {
                var e = this.model.getEdges(a[c]);
                if (e != null) for (d = 0; d < e.length; d++) {
                    var f = this.view.getState(e[d]),
                    g = f != null ? f.getVisibleTerminal(true) : this.view.getVisibleTerminal(e[d], true),
                    h = f != null ? f.getVisibleTerminal(false) : this.view.getVisibleTerminal(e[d], false),
                    k = mxCellPath.create(g),
                    i = mxCellPath.create(h); (b[k] == null || b[i] == null) && this.resetEdge(e[d])
                }
                this.resetEdges(this.model.getChildren(a[c]))
            }
        } finally {
            this.model.endUpdate()
        }
    }
};
mxGraph.prototype.resetEdge = function(a) {
    var b = this.model.getGeometry(a);
    if (b != null && b.points != null && b.points.length > 0) {
        b = b.clone();
        b.points = [];
        this.model.setGeometry(a, b)
    }
    return a
};
mxGraph.prototype.getAllConnectionConstraints = function(a) {
    return a != null && (a.shape != null && a.shape instanceof mxStencilShape) && a.shape.stencil != null ? a.shape.stencil.constraints: null
};
mxGraph.prototype.getConnectionConstraint = function(a, b, c) {
    var b = null,
    d = a.style[c ? mxConstants.STYLE_EXIT_X: mxConstants.STYLE_ENTRY_X];
    if (d != null) {
        var e = a.style[c ? mxConstants.STYLE_EXIT_Y: mxConstants.STYLE_ENTRY_Y];
        e != null && (b = new mxPoint(parseFloat(d), parseFloat(e)))
    }
    d = false;
    b != null && (d = mxUtils.getValue(a.style, c ? mxConstants.STYLE_EXIT_PERIMETER: mxConstants.STYLE_ENTRY_PERIMETER, true));
    return new mxConnectionConstraint(b, d)
};
mxGraph.prototype.setConnectionConstraint = function(a, b, c, d) {
    if (d != null) {
        this.model.beginUpdate();
        try {
            if (d == null || d.point == null) {
                this.setCellStyles(c ? mxConstants.STYLE_EXIT_X: mxConstants.STYLE_ENTRY_X, null, [a]);
                this.setCellStyles(c ? mxConstants.STYLE_EXIT_Y: mxConstants.STYLE_ENTRY_Y, null, [a]);
                this.setCellStyles(c ? mxConstants.STYLE_EXIT_PERIMETER: mxConstants.STYLE_ENTRY_PERIMETER, null, [a])
            } else if (d.point != null) {
                this.setCellStyles(c ? mxConstants.STYLE_EXIT_X: mxConstants.STYLE_ENTRY_X, d.point.x, [a]);
                this.setCellStyles(c ? mxConstants.STYLE_EXIT_Y: mxConstants.STYLE_ENTRY_Y, d.point.y, [a]);
                d.perimeter ? this.setCellStyles(c ? mxConstants.STYLE_EXIT_PERIMETER: mxConstants.STYLE_ENTRY_PERIMETER, null, [a]) : this.setCellStyles(c ? mxConstants.STYLE_EXIT_PERIMETER: mxConstants.STYLE_ENTRY_PERIMETER, "0", [a])
            }
        } finally {
            this.model.endUpdate()
        }
    }
};
mxGraph.prototype.getConnectionPoint = function(a, b) {
    var c = null;
    if (a != null) {
        var d = this.view.getPerimeterBounds(a),
        e = new mxPoint(d.getCenterX(), d.getCenterY()),
        f = a.style[mxConstants.STYLE_DIRECTION],
        g = 0;
        if (f != null) {
            f == "north" ? g = g + 270 : f == "west" ? g = g + 180 : f == "south" && (g = g + 90);
            if (f == "north" || f == "south") {
                d.x = d.x + (d.width / 2 - d.height / 2);
                d.y = d.y + (d.height / 2 - d.width / 2);
                var h = d.width;
                d.width = d.height;
                d.height = h
            }
        }
        if (b.point != null) {
            var k = c = 1,
            i = 0,
            l = 0;
            if (a.shape instanceof mxStencilShape) {
                var m = a.style[mxConstants.STYLE_STENCIL_FLIPH],
                n = a.style[mxConstants.STYLE_STENCIL_FLIPV];
                if (f == "north" || f == "south") {
                    h = m;
                    m = n;
                    n = h
                }
                if (m) {
                    c = -1;
                    i = -d.width
                }
                if (n) {
                    k = -1;
                    l = -d.height
                }
            }
            c = new mxPoint(d.x + b.point.x * d.width * c - i, d.y + b.point.y * d.height * k - l)
        }
        f = a.style[mxConstants.STYLE_ROTATION] || 0;
        if (b.perimeter) {
            if (g != 0 && c != null) {
                h = d = 0;
                g == 90 ? h = 1 : g == 180 ? d = -1 : f == 270 && (h = -1);
                c = mxUtils.getRotatedPoint(c, d, h, e)
            }
            c != null && b.perimeter && (c = this.view.getPerimeterPoint(a, c, false))
        } else f = f + g;
        if (f != 0 && c != null) {
            g = mxUtils.toRadians(f);
            d = Math.cos(g);
            h = Math.sin(g);
            c = mxUtils.getRotatedPoint(c, d, h, e)
        }
    }
    return c
};
mxGraph.prototype.connectCell = function(a, b, c, d) {
    this.model.beginUpdate();
    try {
        var e = this.model.getTerminal(a, c);
        this.cellConnected(a, b, c, d);
        this.fireEvent(new mxEventObject(mxEvent.CONNECT_CELL, "edge", a, "terminal", b, "source", c, "previous", e))
    } finally {
        this.model.endUpdate()
    }
    return a
};
mxGraph.prototype.cellConnected = function(a, b, c, d) {
    if (a != null) {
        this.model.beginUpdate();
        try {
            var e = this.model.getTerminal(a, c);
            this.setConnectionConstraint(a, b, c, d);
            if (this.isPortsEnabled()) {
                d = null;
                if (this.isPort(b)) {
                    d = b.getId();
                    b = this.getTerminalForPort(b, c)
                }
                this.setCellStyles(c ? mxConstants.STYLE_SOURCE_PORT: mxConstants.STYLE_TARGET_PORT, d, [a])
            }
            this.model.setTerminal(a, b, c);
            this.resetEdgesOnConnect && this.resetEdge(a);
            this.fireEvent(new mxEventObject(mxEvent.CELL_CONNECTED, "edge", a, "terminal", b, "source", c, "previous", e))
            
            //post to server by:tk
            if(!c){
                //postCellConnect(a,function(){this.model.endUpdate();});	
            }
        } finally {
            this.model.endUpdate()
        }
    }
};
mxGraph.prototype.disconnectGraph = function(a) {
    if (a != null) {
        this.model.beginUpdate();
        try {
            for (var b = this.view.scale,
            c = this.view.translate,
            d = {},
            e = 0; e < a.length; e++) {
                var f = mxCellPath.create(a[e]);
                d[f] = a[e]
            }
            for (e = 0; e < a.length; e++) if (this.model.isEdge(a[e])) {
                var g = this.model.getGeometry(a[e]);
                if (g != null) {
                    var h = this.view.getState(a[e]),
                    k = this.view.getState(this.model.getParent(a[e]));
                    if (h != null && k != null) {
                        var g = g.clone(),
                        i = -k.origin.x,
                        l = -k.origin.y,
                        m = h.absolutePoints,
                        n = this.model.getTerminal(a[e], true);
                        if (n != null && this.isCellDisconnectable(a[e], n, true)) {
                            for (var o = mxCellPath.create(n); n != null && d[o] == null;) {
                                n = this.model.getParent(n);
                                o = mxCellPath.create(n)
                            }
                            if (n == null) {
                                g.setTerminalPoint(new mxPoint(m[0].x / b - c.x + i, m[0].y / b - c.y + l), true);
                                this.model.setTerminal(a[e], null, true)
                            }
                        }
                        var p = this.model.getTerminal(a[e], false);
                        if (p != null && this.isCellDisconnectable(a[e], p, false)) {
                            for (var q = mxCellPath.create(p); p != null && d[q] == null;) {
                                p = this.model.getParent(p);
                                q = mxCellPath.create(p)
                            }
                            if (p == null) {
                                var t = m.length - 1;
                                g.setTerminalPoint(new mxPoint(m[t].x / b - c.x + i, m[t].y / b - c.y + l), false);
                                this.model.setTerminal(a[e], null, false)
                            }
                        }
                        this.model.setGeometry(a[e], g)
                    }
                }
            }
        } finally {
            this.model.endUpdate()
        }
    }
};
mxGraph.prototype.getCurrentRoot = function() {
    return this.view.currentRoot
};
mxGraph.prototype.getTranslateForRoot = function() {
    return null
};
mxGraph.prototype.isPort = function() {
    return false
};
mxGraph.prototype.getTerminalForPort = function(a) {
    return this.model.getParent(a)
};
mxGraph.prototype.getChildOffsetForCell = function() {
    return null
};
mxGraph.prototype.enterGroup = function(a) {
    a = a || this.getSelectionCell();
    if (a != null && this.isValidRoot(a)) {
        this.view.setCurrentRoot(a);
        this.clearSelection()
    }
};
mxGraph.prototype.exitGroup = function() {
    var a = this.model.getRoot(),
    b = this.getCurrentRoot();
    if (b != null) {
        for (var c = this.model.getParent(b); c != a && !this.isValidRoot(c) && this.model.getParent(c) != a;) c = this.model.getParent(c);
        c == a || this.model.getParent(c) == a ? this.view.setCurrentRoot(null) : this.view.setCurrentRoot(c);
        this.view.getState(b) != null && this.setSelectionCell(b)
    }
};
mxGraph.prototype.home = function() {
    var a = this.getCurrentRoot();
    if (a != null) {
        this.view.setCurrentRoot(null);
        this.view.getState(a) != null && this.setSelectionCell(a)
    }
};
mxGraph.prototype.isValidRoot = function(a) {
    return a != null
};
mxGraph.prototype.getGraphBounds = function() {
    return this.view.getGraphBounds()
};
mxGraph.prototype.getCellBounds = function(a, b, c) {
    var d = [a];
    b && (d = d.concat(this.model.getEdges(a)));
    d = this.view.getBounds(d);
    if (c) for (var c = this.model.getChildCount(a), e = 0; e < c; e++) {
        var f = this.getCellBounds(this.model.getChildAt(a, e), b, true);
        d != null ? d.add(f) : d = f
    }
    return d
};
mxGraph.prototype.getBoundingBoxFromGeometry = function(a, b) {
    var b = b != null ? b: false,
    c = null;
    if (a != null) for (var d = 0; d < a.length; d++) if (b || this.model.isVertex(a[d])) {
        var e = this.getCellGeometry(a[d]);
        if (e != null) {
            var f = e.points;
            if (f != null && f.length > 0) {
                for (var g = new mxRectangle(f[0].x, f[0].y, 0, 0), h = function(a) {
                    a != null && g.add(new mxRectangle(a.x, a.y, 0, 0))
                },
                k = 1; k < f.length; k++) h(f[k]);
                h(e.getTerminalPoint(true));
                h(e.getTerminalPoint(false))
            }
            c == null ? c = new mxRectangle(e.x, e.y, e.width, e.height) : c.add(e)
        }
    }
    return c
};
mxGraph.prototype.refresh = function(a) {
    this.view.clear(a, a == null);
    this.view.validate();
    this.sizeDidChange();
    this.fireEvent(new mxEventObject(mxEvent.REFRESH))
};
mxGraph.prototype.snap = function(a) {
    this.gridEnabled && (a = Math.round(a / this.gridSize) * this.gridSize);
    return a
};
mxGraph.prototype.panGraph = function(a, b) {
    if (this.useScrollbarsForPanning && mxUtils.hasScrollbars(this.container)) {
        this.container.scrollLeft = -a;
        this.container.scrollTop = -b
    } else {
        var c = this.view.getCanvas();
        if (this.dialect == mxConstants.DIALECT_SVG) if (a == 0 && b == 0) {
            mxClient.IS_IE ? c.setAttribute("transform", "translate(" + a + "," + b + ")") : c.removeAttribute("transform");
            if (this.shiftPreview1 != null) {
                for (var d = this.shiftPreview1.firstChild; d != null;) {
                    var e = d.nextSibling;
                    this.container.appendChild(d);
                    d = e
                }
                this.shiftPreview1.parentNode.removeChild(this.shiftPreview1);
                this.shiftPreview1 = null;
                this.container.appendChild(c.parentNode);
                for (d = this.shiftPreview2.firstChild; d != null;) {
                    e = d.nextSibling;
                    this.container.appendChild(d);
                    d = e
                }
                this.shiftPreview2.parentNode.removeChild(this.shiftPreview2);
                this.shiftPreview2 = null
            }
        } else {
            c.setAttribute("transform", "translate(" + a + "," + b + ")");
            if (this.shiftPreview1 == null) {
                this.shiftPreview1 = document.createElement("div");
                this.shiftPreview1.style.position = "absolute";
                this.shiftPreview1.style.overflow = "visible";
                this.shiftPreview2 = document.createElement("div");
                this.shiftPreview2.style.position = "absolute";
                this.shiftPreview2.style.overflow = "visible";
                for (var f = this.shiftPreview1,
                d = this.container.firstChild; d != null;) {
                    e = d.nextSibling;
                    d != c.parentNode ? f.appendChild(d) : f = this.shiftPreview2;
                    d = e
                }
                this.container.insertBefore(this.shiftPreview1, c.parentNode);
                this.container.appendChild(this.shiftPreview2)
            }
            this.shiftPreview1.style.left = a + "px";
            this.shiftPreview1.style.top = b + "px";
            this.shiftPreview2.style.left = a + "px";
            this.shiftPreview2.style.top = b + "px"
        } else {
            c.style.left = a + "px";
            c.style.top = b + "px"
        }
        this.panDx = a;
        this.panDy = b;
        this.fireEvent(new mxEventObject(mxEvent.PAN))
    }
};
mxGraph.prototype.zoomIn = function() {
    this.zoom(this.zoomFactor)
};
mxGraph.prototype.zoomOut = function() {
    this.zoom(1 / this.zoomFactor)
};
mxGraph.prototype.zoomActual = function() {
    if (this.view.scale == 1) this.view.setTranslate(0, 0);
    else {
        this.view.translate.x = 0;
        this.view.translate.y = 0;
        this.view.setScale(1)
    }
};
mxGraph.prototype.zoomTo = function(a, b) {
    this.zoom(a / this.view.scale, b)
};
mxGraph.prototype.zoom = function(a, b) {
    var b = b != null ? b: this.centerZoom,
    c = this.view.scale * a,
    d = this.view.getState(this.getSelectionCell());
    if (this.keepSelectionVisibleOnZoom && d != null) {
        d = new mxRectangle(d.x * a, d.y * a, d.width * a, d.height * a);
        this.view.scale = c;
        if (!this.scrollRectToVisible(d)) {
            this.view.revalidate();
            this.view.setScale(c)
        }
    } else if (b && !mxUtils.hasScrollbars(this.container)) {
        var d = this.container.offsetWidth,
        e = this.container.offsetHeight;
        if (a > 1) var f = (a - 1) / (c * 2),
        d = d * -f,
        e = e * -f;
        else {
            f = (1 / a - 1) / (this.view.scale * 2);
            d = d * f;
            e = e * f
        }
        this.view.scaleAndTranslate(c, this.view.translate.x + d, this.view.translate.y + e)
    } else {
        this.view.setScale(c);
        if (mxUtils.hasScrollbars(this.container)) {
            e = d = 0;
            if (b) {
                d = this.container.offsetWidth * (a - 1) / 2;
                e = this.container.offsetHeight * (a - 1) / 2
            }
            this.container.scrollLeft = Math.round(this.container.scrollLeft * a + d);
            this.container.scrollTop = Math.round(this.container.scrollTop * a + e)
        }
    }
};
mxGraph.prototype.zoomToRect = function(a) {
    var b = this.container.clientWidth / a.width / (this.container.clientHeight / a.height);
    a.x = Math.max(0, a.x);
    a.y = Math.max(0, a.y);
    var c = Math.min(this.container.scrollWidth, a.x + a.width),
    d = Math.min(this.container.scrollHeight, a.y + a.height);
    a.width = c - a.x;
    a.height = d - a.y;
    if (b < 1) {
        b = a.height / b;
        c = (b - a.height) / 2;
        a.height = b;
        b = Math.min(a.y, c);
        a.y = a.y - b;
        d = Math.min(this.container.scrollHeight, a.y + a.height);
        a.height = d - a.y
    } else {
        b = a.width * b;
        c = (b - a.width) / 2;
        a.width = b;
        b = Math.min(a.x, c);
        a.x = a.x - b;
        c = Math.min(this.container.scrollWidth, a.x + a.width);
        a.width = c - a.x
    }
    b = this.container.clientWidth / a.width;
    if (mxUtils.hasScrollbars(this.container)) {
        this.view.setScale(b);
        this.container.scrollLeft = Math.round(a.x * b);
        this.container.scrollTop = Math.round(a.y * b)
    } else this.view.scaleAndTranslate(b, -a.x, -a.y)
};
mxGraph.prototype.fit = function(a, b) {
    if (this.container != null) {
        var a = a != null ? a: 0,
        b = b != null ? b: false,
        c = this.container.clientWidth,
        d = this.container.clientHeight,
        e = this.view.getGraphBounds();
        if (b && e.x != null && e.y != null) {
            e.width = e.width + e.x;
            e.height = e.height + e.y;
            e.x = 0;
            e.y = 0
        }
        var f = this.view.scale,
        g = e.width / f,
        h = e.height / f;
        if (this.backgroundImage != null) {
            g = Math.max(g, this.backgroundImage.width - e.x / f);
            h = Math.max(h, this.backgroundImage.height - e.y / f)
        }
        var k = b ? a: 2 * a,
        c = Math.floor(Math.min(c / (g + k), d / (h + k)) * 100) / 100;
        if ((this.minFitScale == null || c > this.minFitScale) && (this.maxFitScale == null || c < this.maxFitScale)) if (b) this.view.setScale(c);
        else if (mxUtils.hasScrollbars(this.container)) {
            this.view.setScale(c);
            if (e.x != null) this.container.scrollLeft = Math.round(e.x / f) * c - a - Math.max(0, (this.container.clientWidth - g * c) / 2);
            if (e.y != null) this.container.scrollTop = Math.round(e.y / f) * c - a - Math.max(0, (this.container.clientHeight - h * c) / 2)
        } else this.view.scaleAndTranslate(c, e.x != null ? Math.floor(this.view.translate.x - e.x / f + a + 1) : a, e.y != null ? Math.floor(this.view.translate.y - e.y / f + a + 1) : a)
    }
    return this.view.scale
};
mxGraph.prototype.scrollCellToVisible = function(a, b) {
    var c = -this.view.translate.x,
    d = -this.view.translate.y,
    e = this.view.getState(a);
    if (e != null) {
        c = new mxRectangle(c + e.x, d + e.y, e.width, e.height);
        if (b && this.container != null) {
            d = this.container.clientWidth;
            e = this.container.clientHeight;
            c.x = c.getCenterX() - d / 2;
            c.width = d;
            c.y = c.getCenterY() - e / 2;
            c.height = e
        }
        this.scrollRectToVisible(c) && this.view.setTranslate(this.view.translate.x, this.view.translate.y)
    }
};
mxGraph.prototype.scrollRectToVisible = function(a) {
    var b = false;
    if (a != null) {
        var c = this.container.offsetWidth,
        d = this.container.offsetHeight,
        e = Math.min(c, a.width),
        f = Math.min(d, a.height);
        if (mxUtils.hasScrollbars(this.container)) {
            c = this.container;
            a.x = a.x + this.view.translate.x;
            a.y = a.y + this.view.translate.y;
            var g = c.scrollLeft - a.x,
            d = Math.max(g - c.scrollLeft, 0);
            if (g > 0) c.scrollLeft = c.scrollLeft - (g + 2);
            else {
                g = a.x + e - c.scrollLeft - c.clientWidth;
                if (g > 0) c.scrollLeft = c.scrollLeft + (g + 2)
            }
            e = c.scrollTop - a.y;
            g = Math.max(0, e - c.scrollTop);
            if (e > 0) c.scrollTop = c.scrollTop - (e + 2);
            else {
                e = a.y + f - c.scrollTop - c.clientHeight;
                if (e > 0) c.scrollTop = c.scrollTop + (e + 2)
            } ! this.useScrollbarsForPanning && (d != 0 || g != 0) && this.view.setTranslate(d, g)
        } else {
            var g = -this.view.translate.x,
            h = -this.view.translate.y,
            k = this.view.scale;
            if (a.x + e > g + c) {
                this.view.translate.x = this.view.translate.x - (a.x + e - c - g) / k;
                b = true
            }
            if (a.y + f > h + d) {
                this.view.translate.y = this.view.translate.y - (a.y + f - d - h) / k;
                b = true
            }
            if (a.x < g) {
                this.view.translate.x = this.view.translate.x + (g - a.x) / k;
                b = true
            }
            if (a.y < h) {
                this.view.translate.y = this.view.translate.y + (h - a.y) / k;
                b = true
            }
            if (b) {
                this.view.refresh();
                this.selectionCellsHandler != null && this.selectionCellsHandler.refresh()
            }
        }
    }
    return b
};
mxGraph.prototype.getCellGeometry = function(a) {
    return this.model.getGeometry(a)
};
mxGraph.prototype.isCellVisible = function(a) {
    return this.model.isVisible(a)
};
mxGraph.prototype.isCellCollapsed = function(a) {
    return this.model.isCollapsed(a)
};
mxGraph.prototype.isCellConnectable = function(a) {
    return this.model.isConnectable(a)
};
mxGraph.prototype.isOrthogonal = function(a) {
    var b = a.style[mxConstants.STYLE_ORTHOGONAL];
    if (b != null) return b;
    a = this.view.getEdgeStyle(a);
    return a == mxEdgeStyle.SegmentConnector || a == mxEdgeStyle.ElbowConnector || a == mxEdgeStyle.SideToSide || a == mxEdgeStyle.TopToBottom || a == mxEdgeStyle.EntityRelation || a == mxEdgeStyle.OrthConnector
};
mxGraph.prototype.isLoop = function(a) {
    var b = a.getVisibleTerminalState(true),
    a = a.getVisibleTerminalState(false);
    return b != null && b == a
};
mxGraph.prototype.isCloneEvent = function(a) {
    return mxEvent.isControlDown(a)
};
mxGraph.prototype.isToggleEvent = function(a) {
    return mxClient.IS_MAC ? mxEvent.isMetaDown(a) : mxEvent.isControlDown(a)
};
mxGraph.prototype.isGridEnabledEvent = function(a) {
    return a != null && !mxEvent.isAltDown(a)
};
mxGraph.prototype.isConstrainedEvent = function(a) {
    return mxEvent.isShiftDown(a)
};
mxGraph.prototype.isForceMarqueeEvent = function(a) {
    return mxEvent.isAltDown(a)
};
mxGraph.prototype.validationAlert = function(a) {
    mxUtils.alert(a)
};
mxGraph.prototype.isEdgeValid = function(a, b, c) {
    return this.getEdgeValidationError(a, b, c) == null
};
mxGraph.prototype.getEdgeValidationError = function(a, b, c) {
    if (a != null && !this.isAllowDanglingEdges() && (b == null || c == null)) return "";
    if (a != null && this.model.getTerminal(a, true) == null && this.model.getTerminal(a, false) == null) return null;
    if (!this.allowLoops && b == c && b != null || !this.isValidConnection(b, c)) return "";
    if (b != null && c != null) {
        var d = "";
        if (!this.multigraph) {
            var e = this.model.getEdgesBetween(b, c, true);
            if (e.length > 1 || e.length == 1 && e[0] != a) d = d + ((mxResources.get(this.alreadyConnectedResource) || this.alreadyConnectedResource) + "\n")
        }
        var e = this.model.getDirectedEdgeCount(b, true, a),
        f = this.model.getDirectedEdgeCount(c, false, a);
        if (this.multiplicities != null) for (var g = 0; g < this.multiplicities.length; g++) {
            var h = this.multiplicities[g].check(this, a, b, c, e, f);
            h != null && (d = d + h)
        }
        h = this.validateEdge(a, b, c);
        h != null && (d = d + h);
        return d.length > 0 ? d: null
    }
    return this.allowDanglingEdges ? null: ""
};
mxGraph.prototype.validateEdge = function() {
    return null
};
mxGraph.prototype.validateGraph = function(a, b) {
    for (var a = a != null ? a: this.model.getRoot(), b = b != null ? b: {},
    c = true, d = this.model.getChildCount(a), e = 0; e < d; e++) {
        var f = this.model.getChildAt(a, e),
        g = b;
        this.isValidRoot(f) && (g = {});
        g = this.validateGraph(f, g);
        g != null ? this.setCellWarning(f, g.replace(/\n/g, "<br>")) : this.setCellWarning(f, null);
        c = c && g == null
    }
    d = "";
    this.isCellCollapsed(a) && !c && (d = d + ((mxResources.get(this.containsValidationErrorsResource) || this.containsValidationErrorsResource) + "\n"));
    d = this.model.isEdge(a) ? d + (this.getEdgeValidationError(a, this.model.getTerminal(a, true), this.model.getTerminal(a, false)) || "") : d + (this.getCellValidationError(a) || "");
    e = this.validateCell(a, b);
    e != null && (d = d + e);
    this.model.getParent(a) == null && this.view.validate();
    return d.length > 0 || !c ? d: null
};
mxGraph.prototype.getCellValidationError = function(a) {
    var b = this.model.getDirectedEdgeCount(a, true),
    c = this.model.getDirectedEdgeCount(a, false),
    a = this.model.getValue(a),
    d = "";
    if (this.multiplicities != null) for (var e = 0; e < this.multiplicities.length; e++) {
        var f = this.multiplicities[e];
        if (f.source && mxUtils.isNode(a, f.type, f.attr, f.value) && (f.max == 0 && b > 0 || f.min == 1 && b == 0 || f.max == 1 && b > 1)) d = d + (f.countError + "\n");
        else if (!f.source && mxUtils.isNode(a, f.type, f.attr, f.value) && (f.max == 0 && c > 0 || f.min == 1 && c == 0 || f.max == 1 && c > 1)) d = d + (f.countError + "\n")
    }
    return d.length > 0 ? d: null
};
mxGraph.prototype.validateCell = function() {
    return null
};
mxGraph.prototype.getBackgroundImage = function() {
    return this.backgroundImage
};
mxGraph.prototype.setBackgroundImage = function(a) {
    this.backgroundImage = a
};
mxGraph.prototype.getFoldingImage = function(a) {
    if (a != null && this.foldingEnabled && !this.getModel().isEdge(a.cell)) {
        var b = this.isCellCollapsed(a.cell);
        if (this.isCellFoldable(a.cell, !b)) return b ? this.collapsedImage: this.expandedImage
    }
    return null
};
mxGraph.prototype.convertValueToString = function(a) {
    a = this.model.getValue(a);
    if (a != null) {
        if (mxUtils.isNode(a)) return a.nodeName;
        if (typeof a.toString == "function") return a.toString()
    }
    return ""
};
mxGraph.prototype.getLabel = function(a) {
    var b = "";
    if (this.labelsVisible && a != null) {
        var c = this.view.getState(a),
        c = c != null ? c.style: this.getCellStyle(a);
        mxUtils.getValue(c, mxConstants.STYLE_NOLABEL, false) || (b = this.convertValueToString(a))
    }
    return b
};
mxGraph.prototype.isHtmlLabel = function() {
    return this.isHtmlLabels()
};
mxGraph.prototype.isHtmlLabels = function() {
    return this.htmlLabels
};
mxGraph.prototype.setHtmlLabels = function(a) {
    this.htmlLabels = a
};
mxGraph.prototype.isWrapping = function(a) {
    var b = this.view.getState(a),
    a = b != null ? b.style: this.getCellStyle(a);
    return a != null ? a[mxConstants.STYLE_WHITE_SPACE] == "wrap": false
};
mxGraph.prototype.isLabelClipped = function(a) {
    var b = this.view.getState(a),
    a = b != null ? b.style: this.getCellStyle(a);
    return a != null ? a[mxConstants.STYLE_OVERFLOW] == "hidden": false
};
mxGraph.prototype.getTooltip = function(a, b) {
    var c = null;
    if (a != null) {
        if (a.control != null && (b == a.control.node || b.parentNode == a.control.node)) {
            c = this.collapseExpandResource;
            c = mxResources.get(c) || c
        }
        c == null && a.overlays != null && a.overlays.visit(function(a, d) {
            if (c == null && (b == d.node || b.parentNode == d.node)) c = d.overlay.toString()
        });
        if (c == null) {
            var d = this.selectionCellsHandler.getHandler(a.cell);
            d != null && typeof d.getTooltipForNode == "function" && (c = d.getTooltipForNode(b))
        }
        c == null && (c = this.getTooltipForCell(a.cell))
    }
    return c
};
mxGraph.prototype.getTooltipForCell = function(a) {
    var b = null;
    return b = a != null && a.getTooltip != null ? a.getTooltip() : this.convertValueToString(a)
};
mxGraph.prototype.getCursorForCell = function() {
    return null
};
mxGraph.prototype.getStartSize = function(a) {
    var b = new mxRectangle,
    c = this.view.getState(a),
    a = c != null ? c.style: this.getCellStyle(a);
    if (a != null) {
        c = parseInt(mxUtils.getValue(a, mxConstants.STYLE_STARTSIZE, mxConstants.DEFAULT_STARTSIZE));
        mxUtils.getValue(a, mxConstants.STYLE_HORIZONTAL, true) ? b.height = c: b.width = c
    }
    return b
};
mxGraph.prototype.getImage = function(a) {
    return a != null && a.style != null ? a.style[mxConstants.STYLE_IMAGE] : null
};
mxGraph.prototype.getVerticalAlign = function(a) {
    return a != null && a.style != null ? a.style[mxConstants.STYLE_VERTICAL_ALIGN] || mxConstants.ALIGN_MIDDLE: null
};
mxGraph.prototype.getIndicatorColor = function(a) {
    return a != null && a.style != null ? a.style[mxConstants.STYLE_INDICATOR_COLOR] : null
};
mxGraph.prototype.getIndicatorGradientColor = function(a) {
    return a != null && a.style != null ? a.style[mxConstants.STYLE_INDICATOR_GRADIENTCOLOR] : null
};
mxGraph.prototype.getIndicatorShape = function(a) {
    return a != null && a.style != null ? a.style[mxConstants.STYLE_INDICATOR_SHAPE] : null
};
mxGraph.prototype.getIndicatorImage = function(a) {
    return a != null && a.style != null ? a.style[mxConstants.STYLE_INDICATOR_IMAGE] : null
};
mxGraph.prototype.getBorder = function() {
    return this.border
};
mxGraph.prototype.setBorder = function(a) {
    this.border = a
};
mxGraph.prototype.isSwimlane = function(a) {
    if (a != null && this.model.getParent(a) != this.model.getRoot()) {
        var b = this.view.getState(a),
        b = b != null ? b.style: this.getCellStyle(a);
        if (b != null && !this.model.isEdge(a)) return b[mxConstants.STYLE_SHAPE] == mxConstants.SHAPE_SWIMLANE
    }
    return false
};
mxGraph.prototype.isResizeContainer = function() {
    return this.resizeContainer
};
mxGraph.prototype.setResizeContainer = function(a) {
    this.resizeContainer = a
};
mxGraph.prototype.isEnabled = function() {
    return this.enabled
};
mxGraph.prototype.setEnabled = function(a) {
    this.enabled = a
};
mxGraph.prototype.isEscapeEnabled = function() {
    return this.escapeEnabled
};
mxGraph.prototype.setEscapeEnabled = function(a) {
    this.escapeEnabled = a
};
mxGraph.prototype.isInvokesStopCellEditing = function() {
    return this.invokesStopCellEditing
};
mxGraph.prototype.setInvokesStopCellEditing = function(a) {
    this.invokesStopCellEditing = a
};
mxGraph.prototype.isEnterStopsCellEditing = function() {
    return this.enterStopsCellEditing
};
mxGraph.prototype.setEnterStopsCellEditing = function(a) {
    this.enterStopsCellEditing = a
};
mxGraph.prototype.isCellLocked = function(a) {
    var b = this.model.getGeometry(a);
    return this.isCellsLocked() || b != null && this.model.isVertex(a) && b.relative
};
mxGraph.prototype.isCellsLocked = function() {
    return this.cellsLocked
};
mxGraph.prototype.setCellsLocked = function(a) {
    this.cellsLocked = a
};
mxGraph.prototype.getCloneableCells = function(a) {
    return this.model.filterCells(a, mxUtils.bind(this,
    function(a) {
        return this.isCellCloneable(a)
    }))
};
mxGraph.prototype.isCellCloneable = function(a) {
    var b = this.view.getState(a),
    a = b != null ? b.style: this.getCellStyle(a);
    return this.isCellsCloneable() && a[mxConstants.STYLE_CLONEABLE] != 0
};
mxGraph.prototype.isCellsCloneable = function() {
    return this.cellsCloneable
};
mxGraph.prototype.setCellsCloneable = function(a) {
    this.cellsCloneable = a
};
mxGraph.prototype.getExportableCells = function(a) {
    return this.model.filterCells(a, mxUtils.bind(this,
    function(a) {
        return this.canExportCell(a)
    }))
};
mxGraph.prototype.canExportCell = function() {
    return this.exportEnabled
};
mxGraph.prototype.getImportableCells = function(a) {
    return this.model.filterCells(a, mxUtils.bind(this,
    function(a) {
        return this.canImportCell(a)
    }))
};
mxGraph.prototype.canImportCell = function() {
    return this.importEnabled
};
mxGraph.prototype.isCellSelectable = function() {
    return this.isCellsSelectable()
};
mxGraph.prototype.isCellsSelectable = function() {
    return this.cellsSelectable
};
mxGraph.prototype.setCellsSelectable = function(a) {
    this.cellsSelectable = a
};
mxGraph.prototype.getDeletableCells = function(a) {
    return this.model.filterCells(a, mxUtils.bind(this,
    function(a) {
        return this.isCellDeletable(a)
    }))
};
mxGraph.prototype.isCellDeletable = function(a) {
    var b = this.view.getState(a),
    a = b != null ? b.style: this.getCellStyle(a);
    return this.isCellsDeletable() && a[mxConstants.STYLE_DELETABLE] != 0
};
mxGraph.prototype.isCellsDeletable = function() {
    return this.cellsDeletable
};
mxGraph.prototype.setCellsDeletable = function(a) {
    this.cellsDeletable = a
};
mxGraph.prototype.isLabelMovable = function(a) {
    return ! this.isCellLocked(a) && (this.model.isEdge(a) && this.edgeLabelsMovable || this.model.isVertex(a) && this.vertexLabelsMovable)
};
mxGraph.prototype.getMovableCells = function(a) {
    return this.model.filterCells(a, mxUtils.bind(this,
    function(a) {
        return this.isCellMovable(a)
    }))
};
mxGraph.prototype.isCellMovable = function(a) {
    var b = this.view.getState(a),
    b = b != null ? b.style: this.getCellStyle(a);
    return this.isCellsMovable() && !this.isCellLocked(a) && b[mxConstants.STYLE_MOVABLE] != 0
};
mxGraph.prototype.isCellsMovable = function() {
    return this.cellsMovable
};
mxGraph.prototype.setCellsMovable = function(a) {
    this.cellsMovable = a
};
mxGraph.prototype.isGridEnabled = function() {
    return this.gridEnabled
};
mxGraph.prototype.setGridEnabled = function(a) {
    this.gridEnabled = a
};
mxGraph.prototype.isPortsEnabled = function() {
    return this.portsEnabled
};
mxGraph.prototype.setPortsEnabled = function(a) {
    this.portsEnabled = a
};
mxGraph.prototype.getGridSize = function() {
    return this.gridSize
};
mxGraph.prototype.setGridSize = function(a) {
    this.gridSize = a
};
mxGraph.prototype.getTolerance = function() {
    return this.tolerance
};
mxGraph.prototype.setTolerance = function(a) {
    this.tolerance = a
};
mxGraph.prototype.isVertexLabelsMovable = function() {
    return this.vertexLabelsMovable
};
mxGraph.prototype.setVertexLabelsMovable = function(a) {
    this.vertexLabelsMovable = a
};
mxGraph.prototype.isEdgeLabelsMovable = function() {
    return this.edgeLabelsMovable
};
mxGraph.prototype.setEdgeLabelsMovable = function(a) {
    this.edgeLabelsMovable = a
};
mxGraph.prototype.isSwimlaneNesting = function() {
    return this.swimlaneNesting
};
mxGraph.prototype.setSwimlaneNesting = function(a) {
    this.swimlaneNesting = a
};
mxGraph.prototype.isSwimlaneSelectionEnabled = function() {
    return this.swimlaneSelectionEnabled
};
mxGraph.prototype.setSwimlaneSelectionEnabled = function(a) {
    this.swimlaneSelectionEnabled = a
};
mxGraph.prototype.isMultigraph = function() {
    return this.multigraph
};
mxGraph.prototype.setMultigraph = function(a) {
    this.multigraph = a
};
mxGraph.prototype.isAllowLoops = function() {
    return this.allowLoops
};
mxGraph.prototype.setAllowDanglingEdges = function(a) {
    this.allowDanglingEdges = a
};
mxGraph.prototype.isAllowDanglingEdges = function() {
    return this.allowDanglingEdges
};
mxGraph.prototype.setConnectableEdges = function(a) {
    this.connectableEdges = a
};
mxGraph.prototype.isConnectableEdges = function() {
    return this.connectableEdges
};
mxGraph.prototype.setCloneInvalidEdges = function(a) {
    this.cloneInvalidEdges = a
};
mxGraph.prototype.isCloneInvalidEdges = function() {
    return this.cloneInvalidEdges
};
mxGraph.prototype.setAllowLoops = function(a) {
    this.allowLoops = a
};
mxGraph.prototype.isDisconnectOnMove = function() {
    return this.disconnectOnMove
};
mxGraph.prototype.setDisconnectOnMove = function(a) {
    this.disconnectOnMove = a
};
mxGraph.prototype.isDropEnabled = function() {
    return this.dropEnabled
};
mxGraph.prototype.setDropEnabled = function(a) {
    this.dropEnabled = a
};
mxGraph.prototype.isSplitEnabled = function() {
    return this.splitEnabled
};
mxGraph.prototype.setSplitEnabled = function(a) {
    this.splitEnabled = a
};
mxGraph.prototype.isCellResizable = function(a) {
    var b = this.view.getState(a),
    b = b != null ? b.style: this.getCellStyle(a);
    return this.isCellsResizable() && !this.isCellLocked(a) && b[mxConstants.STYLE_RESIZABLE] != 0
};
mxGraph.prototype.isCellsResizable = function() {
    return this.cellsResizable
};
mxGraph.prototype.setCellsResizable = function(a) {
    this.cellsResizable = a
};
mxGraph.prototype.isTerminalPointMovable = function() {
    return true
};
mxGraph.prototype.isCellBendable = function(a) {
    var b = this.view.getState(a),
    b = b != null ? b.style: this.getCellStyle(a);
    return this.isCellsBendable() && !this.isCellLocked(a) && b[mxConstants.STYLE_BENDABLE] != 0
};
mxGraph.prototype.isCellsBendable = function() {
    return this.cellsBendable
};
mxGraph.prototype.setCellsBendable = function(a) {
    this.cellsBendable = a
};
mxGraph.prototype.isCellEditable = function(a) {
    var b = this.view.getState(a),
    b = b != null ? b.style: this.getCellStyle(a);
    return this.isCellsEditable() && !this.isCellLocked(a) && b[mxConstants.STYLE_EDITABLE] != 0
};
mxGraph.prototype.isCellsEditable = function() {
    return this.cellsEditable
};
mxGraph.prototype.setCellsEditable = function(a) {
    this.cellsEditable = a
};
mxGraph.prototype.isCellDisconnectable = function(a) {
    return this.isCellsDisconnectable() && !this.isCellLocked(a)
};
mxGraph.prototype.isCellsDisconnectable = function() {
    return this.cellsDisconnectable
};
mxGraph.prototype.setCellsDisconnectable = function(a) {
    this.cellsDisconnectable = a
};
mxGraph.prototype.isValidSource = function(a) {
    return a == null && this.allowDanglingEdges || a != null && (!this.model.isEdge(a) || this.connectableEdges) && this.isCellConnectable(a)
};
mxGraph.prototype.isValidTarget = function(a) {
    return this.isValidSource(a)
};
mxGraph.prototype.isValidConnection = function(a, b) {
    return this.isValidSource(a) && this.isValidTarget(b)
};
mxGraph.prototype.setConnectable = function(a) {
    this.connectionHandler.setEnabled(a)
};
mxGraph.prototype.isConnectable = function() {
    return this.connectionHandler.isEnabled()
};
mxGraph.prototype.setTooltips = function(a) {
    this.tooltipHandler.setEnabled(a)
};
mxGraph.prototype.setPanning = function(a) {
    this.panningHandler.panningEnabled = a
};
mxGraph.prototype.isEditing = function(a) {
    if (this.cellEditor != null) {
        var b = this.cellEditor.getEditingCell();
        return a == null ? b != null: a == b
    }
    return false
};
mxGraph.prototype.isAutoSizeCell = function(a) {
    var b = this.view.getState(a),
    a = b != null ? b.style: this.getCellStyle(a);
    return this.isAutoSizeCells() || a[mxConstants.STYLE_AUTOSIZE] == 1
};
mxGraph.prototype.isAutoSizeCells = function() {
    return this.autoSizeCells
};
mxGraph.prototype.setAutoSizeCells = function(a) {
    this.autoSizeCells = a
};
mxGraph.prototype.isExtendParent = function(a) {
    return ! this.getModel().isEdge(a) && this.isExtendParents()
};
mxGraph.prototype.isExtendParents = function() {
    return this.extendParents
};
mxGraph.prototype.setExtendParents = function(a) {
    this.extendParents = a
};
mxGraph.prototype.isExtendParentsOnAdd = function() {
    return this.extendParentsOnAdd
};
mxGraph.prototype.setExtendParentsOnAdd = function(a) {
    this.extendParentsOnAdd = a
};
mxGraph.prototype.isConstrainChild = function(a) {
    return this.isConstrainChildren() && !this.getModel().isEdge(this.getModel().getParent(a))
};
mxGraph.prototype.isConstrainChildren = function() {
    return this.constrainChildren
};
mxGraph.prototype.setConstrainChildren = function(a) {
    this.constrainChildren = a
};
mxGraph.prototype.isAllowNegativeCoordinates = function() {
    return this.allowNegativeCoordinates
};
mxGraph.prototype.setAllowNegativeCoordinates = function(a) {
    this.allowNegativeCoordinates = a
};
mxGraph.prototype.getOverlap = function(a) {
    return this.isAllowOverlapParent(a) ? this.defaultOverlap: 0
};
mxGraph.prototype.isAllowOverlapParent = function() {
    return false
};
mxGraph.prototype.getFoldableCells = function(a, b) {
    return this.model.filterCells(a, mxUtils.bind(this,
    function(a) {
        return this.isCellFoldable(a, b)
    }))
};
mxGraph.prototype.isCellFoldable = function(a) {
    var b = this.view.getState(a),
    b = b != null ? b.style: this.getCellStyle(a);
    return this.model.getChildCount(a) > 0 && b[mxConstants.STYLE_FOLDABLE] != 0
};
mxGraph.prototype.isValidDropTarget = function(a, b, c) {
    return a != null && (this.isSplitEnabled() && this.isSplitTarget(a, b, c) || !this.model.isEdge(a) && (this.isSwimlane(a) || this.model.getChildCount(a) > 0 && !this.isCellCollapsed(a)))
};
mxGraph.prototype.isSplitTarget = function(a, b) {
    if (this.model.isEdge(a) && b != null && b.length == 1 && this.isCellConnectable(b[0]) && this.getEdgeValidationError(a, this.model.getTerminal(a, true), b[0]) == null) {
        var c = this.model.getTerminal(a, true),
        d = this.model.getTerminal(a, false);
        return ! this.model.isAncestor(b[0], c) && !this.model.isAncestor(b[0], d)
    }
    return false
};
mxGraph.prototype.getDropTarget = function(a, b, c) {
    if (!this.isSwimlaneNesting()) for (var d = 0; d < a.length; d++) if (this.isSwimlane(a[d])) return null;
    d = mxUtils.convertPoint(this.container, mxEvent.getClientX(b), mxEvent.getClientY(b));
    d.x = d.x - this.panDx;
    d.y = d.y - this.panDy;
    d = this.getSwimlaneAt(d.x, d.y);
    if (c == null) c = d;
    else if (d != null) {
        for (var e = this.model.getParent(d); e != null && this.isSwimlane(e) && e != c;) e = this.model.getParent(e);
        e == c && (c = d)
    }
    for (; c != null && !this.isValidDropTarget(c, a, b) && !this.model.isLayer(c);) c = this.model.getParent(c);
    return ! this.model.isLayer(c) && mxUtils.indexOf(a, c) < 0 ? c: null
};
mxGraph.prototype.getDefaultParent = function() {
    var a = this.defaultParent;
    if (a == null) {
        a = this.getCurrentRoot();
        a == null && (a = this.model.getChildAt(this.model.getRoot(), 0))
    }
    return a
};
mxGraph.prototype.setDefaultParent = function(a) {
    this.defaultParent = a
};
mxGraph.prototype.getSwimlane = function(a) {
    for (; a != null && !this.isSwimlane(a);) a = this.model.getParent(a);
    return a
};
mxGraph.prototype.getSwimlaneAt = function(a, b, c) {
    c = c || this.getDefaultParent();
    if (c != null) for (var d = this.model.getChildCount(c), e = 0; e < d; e++) {
        var f = this.model.getChildAt(c, e),
        g = this.getSwimlaneAt(a, b, f);
        if (g != null) return g;
        if (this.isSwimlane(f) && this.intersects(this.view.getState(f), a, b)) return f
    }
    return null
};
mxGraph.prototype.getCellAt = function(a, b, c, d, e) {
    d = d != null ? d: true;
    e = e != null ? e: true;
    c = c != null ? c: this.getDefaultParent();
    if (c != null) for (var f = this.model.getChildCount(c) - 1; f >= 0; f--) {
        var g = this.model.getChildAt(c, f),
        h = this.getCellAt(a, b, g, d, e);
        if (h != null) return h;
        if (this.isCellVisible(g) && (e && this.model.isEdge(g) || d && this.model.isVertex(g)) && this.intersects(this.view.getState(g), a, b)) return g
    }
    return null
};
mxGraph.prototype.intersects = function(a, b, c) {
    if (a != null) {
        var d = a.absolutePoints;
        if (d != null) for (var a = this.tolerance * this.tolerance,
        e = d[0], f = 1; f < d.length; f++) {
            var g = d[f];
            if (mxUtils.ptSegDistSq(e.x, e.y, g.x, g.y, b, c) <= a) return true;
            e = g
        } else if (mxUtils.contains(a, b, c)) return true
    }
    return false
};
mxGraph.prototype.hitsSwimlaneContent = function(a, b, c) {
    var d = this.getView().getState(a),
    a = this.getStartSize(a);
    if (d != null) {
        var e = this.getView().getScale(),
        b = b - d.x,
        c = c - d.y;
        if (a.width > 0 && b > 0 && b > a.width * e || a.height > 0 && c > 0 && c > a.height * e) return true
    }
    return false
};
mxGraph.prototype.getChildVertices = function(a) {
    return this.getChildCells(a, true, false)
};
mxGraph.prototype.getChildEdges = function(a) {
    return this.getChildCells(a, false, true)
};
mxGraph.prototype.getChildCells = function(a, b, c) {
    a = a != null ? a: this.getDefaultParent();
    a = this.model.getChildCells(a, b != null ? b: false, c != null ? c: false);
    b = [];
    for (c = 0; c < a.length; c++) this.isCellVisible(a[c]) && b.push(a[c]);
    return b
};
mxGraph.prototype.getConnections = function(a, b) {
    return this.getEdges(a, b, true, true, false)
};
mxGraph.prototype.getIncomingEdges = function(a, b) {
    return this.getEdges(a, b, true, false, false)
};
mxGraph.prototype.getOutgoingEdges = function(a, b) {
    return this.getEdges(a, b, false, true, false)
};
mxGraph.prototype.getEdges = function(a, b, c, d, e, f) {
    for (var c = c != null ? c: true, d = d != null ? d: true, e = e != null ? e: true, f = f != null ? f: false, g = [], h = this.isCellCollapsed(a), k = this.model.getChildCount(a), i = 0; i < k; i++) {
        var l = this.model.getChildAt(a, i);
        if (h || !this.isCellVisible(l)) g = g.concat(this.model.getEdges(l, c, d))
    }
    g = g.concat(this.model.getEdges(a, c, d));
    h = [];
    for (i = 0; i < g.length; i++) {
        l = this.view.getState(g[i]);
        k = l != null ? l.getVisibleTerminal(true) : this.view.getVisibleTerminal(g[i], true);
        l = l != null ? l.getVisibleTerminal(false) : this.view.getVisibleTerminal(g[i], false); (e && k == l || k != l && (c && l == a && (b == null || this.isValidAncestor(k, b, f)) || d && k == a && (b == null || this.isValidAncestor(l, b, f)))) && h.push(g[i])
    }
    return h
};
mxGraph.prototype.isValidAncestor = function(a, b, c) {
    return c ? this.model.isAncestor(b, a) : this.model.getParent(a) == b
};
mxGraph.prototype.getOpposites = function(a, b, c, d) {
    var c = c != null ? c: true,
    d = d != null ? d: true,
    e = [],
    f = {};
    if (a != null) for (var g = 0; g < a.length; g++) {
        var h = this.view.getState(a[g]),
        k = h != null ? h.getVisibleTerminal(true) : this.view.getVisibleTerminal(a[g], true),
        h = h != null ? h.getVisibleTerminal(false) : this.view.getVisibleTerminal(a[g], false);
        if (k == b && h != null && h != b && d) {
            var i = mxCellPath.create(h);
            if (f[i] == null) {
                f[i] = h;
                e.push(h)
            }
        } else if (h == b && k != null && k != b && c) {
            i = mxCellPath.create(k);
            if (f[i] == null) {
                f[i] = k;
                e.push(k)
            }
        }
    }
    return e
};
mxGraph.prototype.getEdgesBetween = function(a, b, c) {
    for (var c = c != null ? c: false, d = this.getEdges(a), e = [], f = 0; f < d.length; f++) {
        var g = this.view.getState(d[f]),
        h = g != null ? g.getVisibleTerminal(true) : this.view.getVisibleTerminal(d[f], true),
        g = g != null ? g.getVisibleTerminal(false) : this.view.getVisibleTerminal(d[f], false); (h == a && g == b || !c && h == b && g == a) && e.push(d[f])
    }
    return e
};
mxGraph.prototype.getPointForEvent = function(a, b) {
    var c = mxUtils.convertPoint(this.container, mxEvent.getClientX(a), mxEvent.getClientY(a)),
    d = this.view.scale,
    e = this.view.translate,
    f = b != false ? this.gridSize / 2 : 0;
    c.x = this.snap(c.x / d - e.x - f);
    c.y = this.snap(c.y / d - e.y - f);
    return c
};
mxGraph.prototype.getCells = function(a, b, c, d, e, f) {
    f = f != null ? f: [];
    if (c > 0 || d > 0) {
        var g = a + c,
        h = b + d,
        e = e || this.getDefaultParent();
        if (e != null) for (var k = this.model.getChildCount(e), i = 0; i < k; i++) {
            var l = this.model.getChildAt(e, i),
            m = this.view.getState(l);
            this.isCellVisible(l) && m != null && (m.x >= a && m.y >= b && m.x + m.width <= g && m.y + m.height <= h ? f.push(l) : this.getCells(a, b, c, d, l, f))
        }
    }
    return f
};
mxGraph.prototype.getCellsBeyond = function(a, b, c, d, e) {
    var f = [];
    if (d || e) {
        c == null && (c = this.getDefaultParent());
        if (c != null) for (var g = this.model.getChildCount(c), h = 0; h < g; h++) {
            var k = this.model.getChildAt(c, h),
            i = this.view.getState(k);
            this.isCellVisible(k) && i != null && (!d || i.x >= a) && (!e || i.y >= b) && f.push(k)
        }
    }
    return f
};
mxGraph.prototype.findTreeRoots = function(a, b, c) {
    var b = b != null ? b: false,
    c = c != null ? c: false,
    d = [];
    if (a != null) {
        for (var e = this.getModel(), f = e.getChildCount(a), g = null, h = 0, k = 0; k < f; k++) {
            var i = e.getChildAt(a, k);
            if (this.model.isVertex(i) && this.isCellVisible(i)) {
                for (var l = this.getConnections(i, b ? a: null), m = 0, n = 0, o = 0; o < l.length; o++) this.view.getVisibleTerminal(l[o], true) == i ? m++:n++; (c && m == 0 && n > 0 || !c && n == 0 && m > 0) && d.push(i);
                l = c ? n - m: m - n;
                if (l > h) {
                    h = l;
                    g = i
                }
            }
        }
        d.length == 0 && g != null && d.push(g)
    }
    return d
};
mxGraph.prototype.traverse = function(a, b, c, d, e) {
    if (c != null && a != null) {
        var b = b != null ? b: true,
        e = e || [],
        f = mxCellPath.create(a);
        if (e[f] == null) {
            e[f] = a;
            d = c(a, d);
            if (d == null || d) {
                d = this.model.getEdgeCount(a);
                if (d > 0) for (f = 0; f < d; f++) {
                    var g = this.model.getEdgeAt(a, f),
                    h = this.model.getTerminal(g, true) == a; (!b || h) && this.traverse(this.model.getTerminal(g, !h), b, c, g, e)
                }
            }
        }
    }
};
mxGraph.prototype.isCellSelected = function(a) {
    return this.getSelectionModel().isSelected(a)
};
mxGraph.prototype.isSelectionEmpty = function() {
    return this.getSelectionModel().isEmpty()
};
mxGraph.prototype.clearSelection = function() {
    return this.getSelectionModel().clear()
};
mxGraph.prototype.getSelectionCount = function() {
    return this.getSelectionModel().cells.length
};
mxGraph.prototype.getSelectionCell = function() {
    return this.getSelectionModel().cells[0]
};
mxGraph.prototype.getSelectionCells = function() {
    return this.getSelectionModel().cells.slice()
};
mxGraph.prototype.setSelectionCell = function(a) {
    this.getSelectionModel().setCell(a)
};
mxGraph.prototype.setSelectionCells = function(a) {
    this.getSelectionModel().setCells(a)
};
mxGraph.prototype.addSelectionCell = function(a) {
    this.getSelectionModel().addCell(a)
};
mxGraph.prototype.addSelectionCells = function(a) {
    this.getSelectionModel().addCells(a)
};
mxGraph.prototype.removeSelectionCell = function(a) {
    this.getSelectionModel().removeCell(a)
};
mxGraph.prototype.removeSelectionCells = function(a) {
    this.getSelectionModel().removeCells(a)
};
mxGraph.prototype.selectRegion = function(a, b) {
    var c = this.getCells(a.x, a.y, a.width, a.height);
    this.selectCellsForEvent(c, b);
    return c
};
mxGraph.prototype.selectNextCell = function() {
    this.selectCell(true)
};
mxGraph.prototype.selectPreviousCell = function() {
    this.selectCell()
};
mxGraph.prototype.selectParentCell = function() {
    this.selectCell(false, true)
};
mxGraph.prototype.selectChildCell = function() {
    this.selectCell(false, false, true)
};
mxGraph.prototype.selectCell = function(a, b, c) {
    var d = this.selectionModel,
    e = d.cells.length > 0 ? d.cells[0] : null;
    d.cells.length > 1 && d.clear();
    var d = e != null ? this.model.getParent(e) : this.getDefaultParent(),
    f = this.model.getChildCount(d);
    if (e == null && f > 0) {
        a = this.model.getChildAt(d, 0);
        this.setSelectionCell(a)
    } else if ((e == null || b) && this.view.getState(d) != null && this.model.getGeometry(d) != null) this.getCurrentRoot() != d && this.setSelectionCell(d);
    else if (e != null && c) {
        if (this.model.getChildCount(e) > 0) {
            a = this.model.getChildAt(e, 0);
            this.setSelectionCell(a)
        }
    } else if (f > 0) {
        b = d.getIndex(e);
        if (a) {
            b++;
            a = this.model.getChildAt(d, b % f)
        } else {
            b--;
            a = this.model.getChildAt(d, b < 0 ? f - 1 : b)
        }
        this.setSelectionCell(a)
    }
};
mxGraph.prototype.selectAll = function(a) {
    a = a || this.getDefaultParent();
    a = this.model.getChildren(a);
    a != null && this.setSelectionCells(a)
};
mxGraph.prototype.selectVertices = function(a) {
    this.selectCells(true, false, a)
};
mxGraph.prototype.selectEdges = function(a) {
    this.selectCells(false, true, a)
};
mxGraph.prototype.selectCells = function(a, b, c) {
    c = c || this.getDefaultParent();
    this.setSelectionCells(this.model.filterDescendants(mxUtils.bind(this,
    function(c) {
        return this.view.getState(c) != null && this.model.getChildCount(c) == 0 && (this.model.isVertex(c) && a || this.model.isEdge(c) && b)
    }), c))
};
mxGraph.prototype.selectCellForEvent = function(a, b) {
    var c = this.isCellSelected(a);
    this.isToggleEvent(b) ? c ? this.removeSelectionCell(a) : this.addSelectionCell(a) : (!c || this.getSelectionCount() != 1) && this.setSelectionCell(a)
};
mxGraph.prototype.selectCellsForEvent = function(a, b) {
    this.isToggleEvent(b) ? this.addSelectionCells(a) : this.setSelectionCells(a)
};
mxGraph.prototype.createHandler = function(a) {
    var b = null;
    if (a != null) if (this.model.isEdge(a.cell)) {
        b = this.view.getEdgeStyle(a);
        b = this.isLoop(a) || b == mxEdgeStyle.ElbowConnector || b == mxEdgeStyle.SideToSide || b == mxEdgeStyle.TopToBottom ? new mxElbowEdgeHandler(a) : b == mxEdgeStyle.SegmentConnector || b == mxEdgeStyle.OrthConnector ? new mxEdgeSegmentHandler(a) : new mxEdgeHandler(a)
    } else b = new mxVertexHandler(a);
    return b
};
mxGraph.prototype.addMouseListener = function(a) {
    if (this.mouseListeners == null) this.mouseListeners = [];
    this.mouseListeners.push(a)
};
mxGraph.prototype.removeMouseListener = function(a) {
    if (this.mouseListeners != null) for (var b = 0; b < this.mouseListeners.length; b++) if (this.mouseListeners[b] == a) {
        this.mouseListeners.splice(b, 1);
        break
    }
};
mxGraph.prototype.updateMouseEvent = function(a) {
    if (a.graphX == null || a.graphY == null) {
        var b = mxUtils.convertPoint(this.container, a.getX(), a.getY());
        a.graphX = b.x - this.panDx;
        a.graphY = b.y - this.panDy
    }
};
mxGraph.prototype.fireMouseEvent = function(a, b, c) {
    c == null && (c = this);
    this.updateMouseEvent(b);
    if (a == mxEvent.MOUSE_DOWN) this.isMouseDown = true;
    if (mxClient.IS_TOUCH && this.doubleTapEnabled && a == mxEvent.MOUSE_DOWN) {
        var d = (new Date).getTime();
        if (d - this.lastTouchTime < this.doubleTapTimeout && Math.abs(this.lastTouchX - b.getX()) < this.doubleTapTolerance && Math.abs(this.lastTouchY - b.getY()) < this.doubleTapTolerance) {
            this.lastTouchTime = 0;
            this.dblClick(b.getEvent(), b.getCell());
            b.getEvent().cancelBubble = true
        } else {
            this.lastTouchX = b.getX();
            this.lastTouchY = b.getY();
            this.lastTouchTime = d
        }
    }
    d = b.getEvent().detail != 2;
    if (mxClient.IS_IE && document.compatMode == "CSS1Compat") {
        if (this.lastMouseX != null && Math.abs(this.lastMouseX - b.getX()) > this.doubleTapTolerance || this.lastMouseY != null && Math.abs(this.lastMouseY - b.getY()) > this.doubleTapTolerance) d = true;
        if (a == mxEvent.MOUSE_UP) {
            this.lastMouseX = b.getX();
            this.lastMouseY = b.getY()
        }
    }
    if ((a != mxEvent.MOUSE_UP || this.isMouseDown) && d) {
        if (a == mxEvent.MOUSE_UP) this.isMouseDown = false;
        if (!this.isEditing() && (mxClient.IS_OP || mxClient.IS_SF || mxClient.IS_GC || mxClient.IS_IE && mxClient.IS_SVG || b.getEvent().target != this.container)) {
            a == mxEvent.MOUSE_MOVE && (this.isMouseDown && this.autoScroll) && this.scrollPointToVisible(b.getGraphX(), b.getGraphY(), this.autoExtend);
            if (this.mouseListeners != null) {
                c = [c, b];
                b.getEvent().returnValue = true;
                for (d = 0; d < this.mouseListeners.length; d++) {
                    var e = this.mouseListeners[d];
                    a == mxEvent.MOUSE_DOWN ? e.mouseDown.apply(e, c) : a == mxEvent.MOUSE_MOVE ? e.mouseMove.apply(e, c) : a == mxEvent.MOUSE_UP && e.mouseUp.apply(e, c)
                }
            }
            a == mxEvent.MOUSE_UP && this.click(b)
        }
    } else if (a == mxEvent.MOUSE_UP) this.isMouseDown = false
};
mxGraph.prototype.destroy = function() {
    if (!this.destroyed) {
        this.destroyed = true;
        this.tooltipHandler != null && this.tooltipHandler.destroy();
        this.selectionCellsHandler != null && this.selectionCellsHandler.destroy();
        this.panningHandler != null && this.panningHandler.destroy();
        this.connectionHandler != null && this.connectionHandler.destroy();
        this.graphHandler != null && this.graphHandler.destroy();
        this.cellEditor != null && this.cellEditor.destroy();
        this.view != null && this.view.destroy();
        if (this.model != null && this.graphModelChangeListener != null) {
            this.model.removeListener(this.graphModelChangeListener);
            this.graphModelChangeListener = null
        }
        this.container = null
    }
};